自己动手写数据结构之双向链表

双向链表的实现

1 定义

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

2 基本元素

链表头 First

链表尾 Last

节点 Node

节点中数据域 data

节点中指针域 next

节点中指针域 prev

3 基本操作

表头插入 insertFirst

表尾插入 insertLast

指定特定值的节点之后插入 insertAfter

表头删除 deleteFirst

表尾删除 deleteLast

4 基本思路

insertFirst

添加第一个结点时

头结点和尾结点均指向新结点

first = newNode

last = newNode

添加新结点时

(1) 头结点指向新结点 first = newNode

(2) 新结点的next指向原有头结点 newNode.next = first

(3) 原有头结点的prev指向新结点 first.prev = newNode

(4) 尾结点指向原头结点,保持不变

代码实现

    public void insertFirst(int data){
        Node newNode = new Node(data);
        if (isEmpty()){
            last = newNode;
        }else {
            //将原结点的前指针同新结点相连
            first.prev = newNode;
        }

        newNode.next = first;

        first = newNode;

    }

insertLast

添加第一个结点时

头结点和尾结点均指向新结点

first = newNode

last = newNode

新结点的prev指向null

添加新结点时

(1)头结点不变

(2)尾结点指向新结点 last = newNode

(3)原尾结点的next指向新结点 last.next = newNode

(4)新结点的prev指向原尾结点 newNode.prev = last

代码实现

public void insertLast(int data){
        Node newNode = new Node(data);

        if (isEmpty()){
            first = newNode;
        }else {
            //将原结点的后指针同新结点相连
            last.next = newNode;
            newNode.prev = last;
        }
        
        last = newNode;
    }

insertAfter

先找到当前结点

代码实现

    public Node find(int data){

        Node current = first;

        while (current.data != data){
            if (current.next == null){
                return null;
            }else {
                current = current.next;
            }
        }

        return current;

    }

要插入结点为最后一个

(1) 尾结点指向新结点 last = newNode

(2) 当前结点next指向新结点 current.next = newNode

(3) 新结点的prev指向当前结点 newNode.prev = current

(4) 新结点的next指向null newNode.next = null

要插入结点为中间结点

(1) 头尾结点保持不变

(2) 当前结点的next指向指向新结点 current.next = newNode

(3) 新结点的prev指向当前结点 newNode.prev = current

(4) 新结点的next指向当前结点的下一结点 newNode.next = current.next

(5) 当前结点下一结点的prev指向新结点 current.next.prev = newNode

代码实现

    public void insertAfter(int targetData, int newData){
        Node current = find(targetData);

        Node newNode = new Node(newData);

        if (current != null){
            if (current == last){
                last = newNode;
                newNode.next = null;
            }else {
                newNode.next = current.next;
                current.next.prev = newNode;
            }

            current.next = newNode;
            newNode.prev = current;
        }
    }

deleteFirst

只有一个结点

(1) 头尾结点均为null first,last = null

有多个结点

(1) 头结点指向原头结点的下一结点 first = first.next

(2) 原头结点的下一结点prev为null first.next.prev = null

代码实现

    public int deleteFirst(){
        int temp = first.data;
        if (first.next == null){
            last = null;
        }else {
            first.next.prev = null;
        }
        first = first.next;
        return temp;
    }

deleteLast

只有一个结点

(1) 头尾结点均为null first,last = null

有多个结点

(1) 尾结点指向原尾结点的上一结点 last = last.prev

(2) 原尾结点上一结点的next指向null last.prev.next = null

代码实现

    public int deleteLast(){
        int temp = first.data;
        if (first.next == null){
            first = null;
        }else {
            last.prev.next = null;
        }
        last = last.prev;
        return temp;
    }

deleteKey

被删除的是第一个结点

(1)头结点指向当前结点下一结点 first = current.next

(2)当前结点下一结点的prev为null,current.next.prev = null 被删除的是最后一个结点

(1)尾结点指向当前结点上一结点,last = current.prev

(2)当前结点上一结点的next为null, current.prev.next = null 被删除的是中间结点

(1) 尾结点指向当前结点下一结点 last = current.next

(2) 当前结点上一结点的next指向当前结点的下一结点 current.prev.next = current.next

(3) 当前结点下一结点的prev指向当前结点的上一结点 current.next.prev = current.prev

代码实现

public int deleteKey(int data){
        Node current = find(data);
        if (current != null){
            if (current == first){
                first = current.next;
            }else {
                current.prev.next = current.next;
            }

            if (current == last){
                last = current.prev;
            }else {
                current.next.prev = current.prev;
            }

            return current.data;
        }

        return 0;
    }

你可能感兴趣的:(自己动手写数据结构之双向链表)