手写双链表结构

433 阅读1分钟

定义链表结构

public class DoubleLinkList<T> {

    private Node head;
    private Node last;
    private int size;
}

定义node结构

 public class Node<T> {
        private T data;
        private Node<T> pre;
        private Node<T> next;


        public Node(T data, Node<T> pre, Node<T> next) {
            this.data = data;
            this.pre = pre;
            this.next = next;
        }
    }

定义添加node

 /**
     * 如果便于理解的话 也可以 分三种情况写  插入最后, 插入第一个,插入中间
     * @param data
     * @param index
     */
    public void add(T data, int index) {
        if (index == size) { // 插入到最后
            addLast(data);
        } else {
            addFirst(data, index);
        }

    }

    public void add(T data) {
        addLast(data);
    }

    /**
     * 从指定位置添加
     * (==null)-----newnode----old
     * (!=null)pre------newnode------old
     *
     * @param data
     */
    private void addFirst(T data, int index) {
        Node<T> oldNode = getNode(index);//获取老的位置节点  新节点插入前面
        Node<T> pre = oldNode.pre;
        Node<T> newNode = new Node<>(data, pre, oldNode);
        oldNode.pre = newNode;
        if (pre == null) {//说明至少一个  先走addlast 至少会添加一个
            head = newNode;//重新指定head 为新创建的node
        } else {
            pre.next = newNode;
        }
    }

    /**
     * 从最后添加
     *
     * @param data
     */
    private void addLast(T data) {
        Node<T> temp = last;// 取出最后一个node
        Node<T> newNode = new Node<>(data, temp, null); //新节点前一个节点即是 最后一个last节点 自己为last节点 next 节点为空
        last = newNode;// 最后一个节点为当前节点 赋值新的尾部
        if (temp == null) {//当前暂无节点 size=0
            head = newNode; // 头部和尾部一样 第一个节点
        } else {
            //添加尾部 头部不用考虑, 尾部已经赋值  然后把它们串起来就ok了
            temp.next = newNode;
        }
        size++;
    }

获取node节点

    //查询指定索引的结点
    Node getNode(int index) {
        if (index < (size >> 1)) {  //如果索引在前一半。从前往后找
            Node x = head;
            for (int i = 0; i < index; i++) {
                x = x.next;
            }
            return x;
        } else {              //索引在后一半,从后往前找
            Node x = last;
            for (int i = size - 1; i > index; i--) {
                x = x.pre;
            }
            return x;
        }
    }

删除某个节点数据

  /**  pre-----deletenode---next
     * 删除元素
     */
    public void remove(int index) {
        if (size == 0 || index < 0 || index > size - 1) {
            return;
        }
        Node<T> node = getNode(index);
        Node<T> preNode = node.pre;
        Node<T> nextNode = node.next;

        if (preNode == null) {//当前为第一个
            head = nextNode;
        } else if (nextNode == null) {
            last = preNode;// 为最后一个
        } else {
            preNode.next = nextNode;
            nextNode.pre = preNode;
        }
        size--;
    }