跳至主要內容

双向链表


双向链表

介绍

双向链表(Doubly Linked List)是一种常见的数据结构,它与单链表类似,但每个节点除了包含指向下一个节点的指针外,还包含指向前一个节点的指针。这种结构使得在双向链表中可以进行双向遍历,即可以从前向后或从后向前访问节点。

每个节点在双向链表中包含三个主要部分:

  1. 数据元素:用于存储具体的数据,可以是任意类型的数据,例如整数、字符、对象等。
  2. 指向前一个节点的指针:指向链表中的前一个节点。
  3. 指向下一个节点的指针:指向链表中的后一个节点。

双向链表的特点包括:

  • 链表中的节点在内存中可以不连续存储,它们通过指针相互连接。
  • 链表的大小可以动态调整,可以在任意位置插入或删除节点。
  • 可以从前向后或从后向前遍历链表,因为每个节点都有指向前一个节点和后一个节点的指针。

双向链表的操作包括:

  • 遍历链表:可以从头节点开始向后遍历,也可以从尾节点开始向前遍历。
  • 插入节点:在指定位置插入一个新节点。
  • 删除节点:删除指定位置的节点。
  • 查找节点:根据特定条件查找链表中的节点。

双向链表相比于单链表的优势在于可以更方便地进行反向遍历和删除操作,但它也需要更多的内存空间来存储额外的指针。

双向链表在实际应用中常用于需要频繁在任意位置插入和删除节点,并且需要双向遍历的情况下,提供了更高的灵活性和效率。

代码实现

public class DoublyLinkedList<T> {
    public class Node {
        public T data;
        public Node nextNode;
        public Node prevNode;
    }

    public Node headNode;
    public int size;

    public DoublyLinkedList() {
        this.headNode = null;
    }

    public boolean isEmpty() {
        if (headNode == null)
            return true;
        return false;   
    }

    public void insertAtHead(T data) {
        Node newNode = new Node();
        newNode.data = data;
        newNode.nextNode = this.headNode; 
        newNode.prevNode = null;
        if (headNode != null)
            headNode.prevNode = newNode;
        this.headNode = newNode;
        size++;
    }

    public void printList() {
        if (isEmpty()) {
            System.out.println("List is Empty!");
            return;
        }
        Node temp = headNode;
        System.out.print("List : null <- ");
        while (temp.nextNode != null) {
            System.out.print(temp.data.toString() + " <-> ");
            temp = temp.nextNode;
        }
        System.out.println(temp.data.toString() + " -> null");
    }
    public void deleteAtHead(){
        if(isEmpty())
            return;
        headNode = headNode.nextNode;
        headNode.prevNode = null;
        size--;
    }
    public void deleteByValue(T data) {
        if (isEmpty())
            return;

        Node currentNode = this.headNode;

        if (currentNode.data.equals(data)) {
            deleteAtHead();
            return;
        }
        while (currentNode != null) {
            if (data.equals(currentNode.data)) {
                currentNode.prevNode.nextNode = currentNode.nextNode;
                if(currentNode.nextNode != null)
                    currentNode.nextNode.prevNode = currentNode.prevNode;
                size--;
            }
            currentNode = currentNode.nextNode;
        }
    }
}

上次编辑于:
贡献者: Neil