📜  双向链表 C++ 代码 - C++ (1)

📅  最后修改于: 2023-12-03 15:07:22.719000             🧑  作者: Mango

双向链表 C++ 代码

简介

双向链表(Doubly Linked List)是一种常用的动态数据结构,它能够高效地支持插入、删除和查找操作。和单向链表不同的是,双向链表中每个节点都有两个指针,分别指向前一个节点和后一个节点。

实现

以下是基于C++的双向链表实现代码:

#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* prev;
    Node* next;
};

class DoublyLinkedList {
private:
    Node* head;
    Node* tail;
public:
    DoublyLinkedList() {
        head = nullptr;
        tail = nullptr;
    }
    
    void append(int data) {
        Node* node = new Node;
        node->data = data;
        node->prev = tail;
        node->next = nullptr;
        
        if (tail == nullptr) {
            head = node;
        } else {
            tail->next = node;
        }
        
        tail = node;
    }
    
    void prepend(int data) {
        Node* node = new Node;
        node->data = data;
        node->prev = nullptr;
        node->next = head;
        
        if (head == nullptr) {
            tail = node;
        } else {
            head->prev = node;
        }
        
        head = node;
    }
    
    void remove(int data) {
        Node* node = head;
        while (node != nullptr) {
            if (node->data == data) {
                if (node == head) {
                    head = node->next;
                    if (head != nullptr) {
                        head->prev = nullptr;
                    }
                } else if (node == tail) {
                    tail = node->prev;
                    if (tail != nullptr) {
                        tail->next = nullptr;
                    }
                } else {
                    node->prev->next = node->next;
                    node->next->prev = node->prev;
                }
                delete node;
                return;
            }
            node = node->next;
        }
    }
    
    void print() {
        Node* node = head;
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};

int main() {
    DoublyLinkedList list;
    list.append(1);
    list.append(2);
    list.append(3);
    list.append(4);
    list.prepend(0);
    list.remove(3);
    list.print(); // 0 1 2 4
    return 0;
}
代码讲解
Node 结构体

我们首先定义一个 Node 结构体,表示链表中的一个节点。它包含三个成员变量:数据(data)和前后指针(prevnext)。它们都是指针类型,因为它们需要指向其他节点。

DoublyLinkedList 类

然后我们定义一个 DoublyLinkedList 类,表示双向链表。它包含两个成员变量:头节点(head)和尾节点(tail)。它们都是指向 Node 结构体的指针。在默认构造函数中,我们将它们都初始化为 nullptr

append 方法

append 方法用于向双向链表的尾部添加一个新的节点。首先我们创建一个新的节点,然后将其数据(data)设置为传入的参数值。然后将它的前指针(prev)设置为原来的尾节点(如果链表为空,则前指针为 nullptr),后指针(next)设置为 nullptr。接着,如果链表为空,则将头节点(head)指向这个新节点;否则,将原来的尾节点(tail)的后指针(next)指向这个新节点。最后,更新尾节点(tail),使其指向这个新节点。

prepend 方法

prepend 方法用于向双向链表的头部添加一个新的节点。首先我们创建一个新的节点,然后将其数据(data)设置为传入的参数值。然后将它的前指针(prev)设置为 nullptr,后指针(next)设置为原来的头节点(如果链表为空,则后指针为 nullptr)。接着,如果链表为空,则将尾节点(tail)指向这个新节点;否则,将原来的头节点(head)的前指针(prev)指向这个新节点。最后,更新头节点(head),使其指向这个新节点。

remove 方法

remove 方法用于从双向链表中删除一个值等于传入参数的节点。首先我们从头节点开始遍历链表,查找数据为传入值的节点。如果找到了这样的节点,则分为以下几种情况进行处理:

  • 如果这个节点是头节点:则将头节点(head)指向它的后继节点,如果它有后继节点,则将后继节点的前指针(prev)设置为 nullptr
  • 如果这个节点是尾节点:则将尾节点(tail)指向它的前驱节点,如果它有前驱节点,则将前驱节点的后指针(next)设置为 nullptr
  • 如果这个节点既不是头节点也不是尾节点:则将它的前驱节点的后指针(next)设置为它的后继节点,将它的后继节点的前指针(prev)设置为它的前驱节点。
  • 最后,释放这个节点的内存空间。

print 方法

print 方法用于打印双向链表中的所有节点的数据。首先从头节点(head)开始遍历链表,输出每个节点的数据(data),然后将当前节点的指针(next)指向下一个节点。如果当前节点为空,则停止遍历。

总结

双向链表是一种非常有效的数据结构,我们可以利用它高效地实现很多常见的操作。在 C++ 中,我们可以通过定义 Node 结构体和 DoublyLinkedList 类来实现双向链表。