Java实现双链表插入排序~渡星河全网首发

渡星河
2022-11-23 / 0 评论 / 103 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年04月18日,已超过510天没有更新,若内容或图片失效,请留言反馈。

测试类

package test;

public class TestLinkedList {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
      //在双链表尾部添加节点
        list.addLast("cab");
        list.addLast("bba");
        list.addLast("bab");
        list.addLast("abb");
        list.addLast("bab");
      //在双链表头部添加节点
        list.addFirst("aaa");
        System.out.println("--------------排序----------------");
      //调用插入排序方法
        list.insertSort();
      //调用遍历函数
        list.travers();

    }
}

下面是插入排序的方法

public void insertSort() {
        Node curr = first.next;//开始时从第二个节点开始往前看
        while(curr != null) {
            Node prev = curr.prev;
            while(prev != null) {
                if (curr.data.compareTo(prev.data) < 0) {//如果当前节点小于前一个节点就继续往前查看
                    prev = prev.prev;
                } else break;
            }
            //因为在之后会改变当前节点的位置,所以先定义临时变量记录改变前的节点位置
            Node cNext = curr.next;

            if (prev == null) {//如果找到的插入位置为头部直接删除节点后调用头插法
                String val = curr.data;
                unlink(curr);
                addFirst(val);
            } else {
              //此部分逻辑完成把当前节点的前驱后后继关联上
              //然后把当前节点插入到应该存在的位置,也就是prev之后。
                curr.prev.next = curr.next;
                if (curr.next != null) {
                    curr.next.prev = curr.prev;
                }
                curr.next = prev.next;
                prev.next.prev = curr;
                prev.next = curr;
                curr.prev = prev;
            }
            curr = cNext;
        }
    }

方法类调式的时候使用这个

/*双链表测试类*/
public class TestLinkedList {
    public static void main(String[] args) {
        //要访问双链表中的方法,就需要使用new关键字创建该双链表的对象。
        LinkedList list = new LinkedList();
        //String str = new String("abc");
        //调用list的添加方法
        list.add("dcd");
        list.add("bbc");
        list.add("fgh");
        list.add("bbc");
        list.add("abc");
        //调用遍历方法
        //list.traverse();
        //list.addFirst("world");
        //list.remove(-2);
        //list.insert(4, "world");
        list.traverse();
        list.insertSort();
        list.traverse();

    }
}

/*
实现双链表
该类里的属性和方法都没有用关键字static修饰
所以访问这些属性和方法的时候都要使用对象的引用取访问
*/
class LinkedList {
    //头节点
    Node first = null;
    //尾节点
    Node last = null;
    //记录节点个数
    int size = 0;
    /*定义添加元素的方法*/
    public void add(String val) {
        addLast(val);
    }
    /*尾插法*/
    public void addLast(String val) {
        //要把val添加到链表中,需要做什么?
        //第一步:创建节点,
        Node newNode = new Node();
        //第二步:把值val存入节点的数据区域
        newNode.data = val;
        //首次添加节点时,头节点和尾节点都是null.
        if(last == null) {
            //首次添加需要把头节点和尾节点的引用都移动到指向第一个节点
            first = newNode;
            last = newNode;
        } else {//非首次插入节点
            last.next = newNode;//让链表的末节点的next域指向新创建的节点
            newNode.prev = last;//让新创建节点的prev域指向链表的末节点
            last = newNode;//最后把last移动到指向新创建的节点
        }
        size++;
    }
    /*头插法*/
    public void addFirst(String val) {
        //要把val添加到链表中,需要做什么?
        //第一步:创建节点,
        Node newNode = new Node();
        //第二步:把值val存入节点的数据区域
        newNode.data = val;
        //首次插入值头和尾节点都是null
        if(first == null) {
            first = newNode;
            last = newNode;
        } else {
            newNode.next = first;
            first.prev = newNode;
            first = newNode;
        }
        size++;
    }
    /*检查位置边界*/
    public void checkBoundary(int position) {
        if (position < 0 || position > size)
            throw new RuntimeException("下标过了啊。。。。。。");
    }
    /*该方法根据指定位置返回节点*/
    public Node node(int position) {
        //定义临时遍历记录头节点
        Node x = first;
        //查找position位置处的节点
        for (int i = 1; i < position; i++) {
            x = x.next;
        }
        return x;
    }

    /*解除节点的关系*/
    public Node unlink(Node x){
        //定义变量记录需要删除的节点
        Node item = x;
        //记录当前节点的next;
        Node next = x.next;
        //记录当前节点的prev
        Node prev = x.prev;
        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }
        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }
        //x.data = null;
        size--;
        return item;
    }
    /*删除节点*/
    public Node remove(int position) {
        //位置检查
        checkBoundary(position);
        //调用方法根据位置查找节点
        Node node = node(position);
        //解除引用并返回
        return unlink(node);
    }

    /*把指定节点的数据域更新为指定的值*/
    public void update(int position, String value) {
        //检查边界
        checkBoundary(position);
        //查找需要更新的节点并设置新的值
        node(position).data = value;
    }

    /*获取指定节点的值*/
    public String get(int position) {
        return node(position).data;
    }

    /*指定位置插入一个节点*/
    public void insert(int position, String value) {
        //单独处理插链表尾部
        if((size + 1) == position) {
            addLast(value);
            return;
        }
        //单独处理插入链表头部
        if (position == 1) {
            addFirst(value);
            return;
        }
        //查找到需要插入节点的位置
        Node node = node(position);

        //获取当前节点的前一个节点
        Node prevNode = node.prev;
        //创建节点
        Node newNode = createNode(value);
        prevNode.next = newNode;
        newNode.prev = prevNode;

        newNode.next = node;
        node.prev = newNode;
        size++;
    }

    /*创建节点*/
    public Node createNode(String val) {
        Node node = new Node();
        node.data = val;
        return node;
    }

    /*去除重复节点*/
    public void distinct() {
        Node one = first;
        int outSize = 1;
        while(one != null) {
            Node two = one.next;
            int count = outSize + 1;
            while(two != null) {
                if (one.data == two.data) {
                    two = two.next;
                    remove(count);
                } else {
                    two = two.next;
                    count++;
                }
            }
            outSize++;
            one = one.next;
        }
    }

    public void insertSort() {
        Node curr = first.next;//开始时从第二个节点开始往前看
        while(curr != null) {
            Node prev = curr.prev;
            while(prev != null) {
                if (curr.data.compareTo(prev.data) < 0) {//如果当前节点小于前一个节点就继续往前查看
                    prev = prev.prev;
                } else break;
            }
            //因为在之后会改变当前节点的位置,所以先定义临时变量记录改变前的节点位置
            Node cNext = curr.next;

            if (prev == null) {//如果找到的插入位置为头部直接删除节点后调用头插法
                String val = curr.data;
                unlink(curr);
                addFirst(val);
            } else {
              //此部分逻辑完成把当前节点的前驱后后继关联上
              //然后把当前节点插入到应该存在的位置,也就是prev之后。
                curr.prev.next = curr.next;
                if (curr.next != null) {
                    curr.next.prev = curr.prev;
                }
                curr.next = prev.next;
                prev.next.prev = curr;
                prev.next = curr;
                curr.prev = prev;
            }
            curr = cNext;
        }
    }


    /*遍历链表*/
    public void traverse() {
        Node temp = first;
        while(temp != null) {
            System.out.print(temp.data + "  ");
            temp = temp.next;
        }
        System.out.println();
    }
}

class Node {
    //数据域
    String data;
    //前驱引用
    Node prev;
    //后继引用
    Node next;
}

2

评论 (0)

取消