返回

双向链表快速入门指南:增删查改操作轻松搞定

后端

什么是双向链表?

双向链表是一种特殊类型的链表,它允许在链表中的任何位置进行高效的增删查改操作。与单向链表不同,双向链表中的每个节点都包含指向其前一个节点和后一个节点的指针。这种设计使双向链表能够支持更广泛的操作,例如从链表的中间位置插入或删除节点。

双向链表的增删查改操作

插入节点

要在双向链表中插入一个新节点,我们需要遵循以下步骤:

  1. 创建一个新的节点,并将数据存储在该节点中。
  2. 将新节点的prev指针指向要插入节点的前一个节点。
  3. 将新节点的next指针指向要插入节点的后一个节点。
  4. 将要插入节点的前一个节点的next指针指向新节点。
  5. 将要插入节点的后一个节点的prev指针指向新节点。

删除节点

要从双向链表中删除一个节点,我们需要遵循以下步骤:

  1. 将要删除节点的前一个节点的next指针指向要删除节点的后一个节点。
  2. 将要删除节点的后一个节点的prev指针指向要删除节点的前一个节点。
  3. 将要删除节点的prev和next指针设置为null。

查找节点

要查找双向链表中的一个节点,我们需要遵循以下步骤:

  1. 从链表的头部或尾部开始遍历。
  2. 将当前节点与要查找的节点进行比较。
  3. 如果当前节点与要查找的节点匹配,则返回当前节点。
  4. 如果当前节点不与要查找的节点匹配,则将当前节点的next或prev指针指向下一个节点,并重复步骤2和3。

修改节点

要修改双向链表中的一个节点,我们需要遵循以下步骤:

  1. 找到要修改的节点。
  2. 将要修改的节点的数据更新为新的数据。
  3. 将要修改的节点的prev或next指针更新为新的指针。

完整代码示例

class Node {
    int data;
    Node prev;
    Node next;

    public Node(int data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}

class DoublyLinkedList {
    Node head;
    Node tail;

    public DoublyLinkedList() {
        this.head = null;
        this.tail = null;
    }

    public void insertAtHead(int data) {
        Node newNode = new Node(data);
        if (this.head == null) {
            this.head = newNode;
            this.tail = newNode;
        } else {
            newNode.next = this.head;
            this.head.prev = newNode;
            this.head = newNode;
        }
    }

    public void insertAtTail(int data) {
        Node newNode = new Node(data);
        if (this.tail == null) {
            this.head = newNode;
            this.tail = newNode;
        } else {
            newNode.prev = this.tail;
            this.tail.next = newNode;
            this.tail = newNode;
        }
    }

    public void insertAfter(Node prevNode, int data) {
        if (prevNode == null) {
            throw new IllegalArgumentException("Previous node cannot be null");
        }

        Node newNode = new Node(data);
        newNode.next = prevNode.next;
        prevNode.next = newNode;
        newNode.prev = prevNode;
        if (newNode.next != null) {
            newNode.next.prev = newNode;
        } else {
            this.tail = newNode;
        }
    }

    public void insertBefore(Node nextNode, int data) {
        if (nextNode == null) {
            throw new IllegalArgumentException("Next node cannot be null");
        }

        Node newNode = new Node(data);
        newNode.prev = nextNode.prev;
        nextNode.prev = newNode;
        newNode.next = nextNode;
        if (newNode.prev != null) {
            newNode.prev.next = newNode;
        } else {
            this.head = newNode;
        }
    }

    public void deleteNode(Node node) {
        if (node == null) {
            throw new IllegalArgumentException("Node cannot be null");
        }

        if (node == this.head) {
            this.head = node.next;
            if (this.head != null) {
                this.head.prev = null;
            }
        } else if (node == this.tail) {
            this.tail = node.prev;
            if (this.tail != null) {
                this.tail.next = null;
            }
        } else {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
    }

    public Node findNode(int data) {
        Node current = this.head;
        while (current != null) {
            if (current.data == data) {
                return current;
            }
            current = current.next;
        }
        return null;
    }

    public void printList() {
        Node current = this.head;
        while (current != null) {
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
}

结语

双向链表是一种强大的数据结构,它允许在链表中的任何位置进行高效的增删查改操作。本指南详细讲解了双向链表的增删查改操作,并提供了完整的代码示例,帮助您轻松掌握双向链表的实现和应用。