📅  最后修改于: 2023-12-03 15:07:22.719000             🧑  作者: Mango
双向链表(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
结构体,表示链表中的一个节点。它包含三个成员变量:数据(data
)和前后指针(prev
和 next
)。它们都是指针类型,因为它们需要指向其他节点。
然后我们定义一个 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
类来实现双向链表。