一、基本概念
双向链表是一种常见的数据结构,每个节点包含两个指针,分别指向前驱节点和后继节点。与单向链表相比,双向链表可以从任意节点向前或向后遍历,操作更灵活。
二、节点定义
在C语言中,双向链表的节点通常定义为结构体,包含数据域和两个指针域:
c
typedef struct Node {
int data; // 数据域
struct Node *prev; // 指向前驱节点
struct Node *next; // 指向后继节点
} Node;
三、创建双向链表
初始化一个双向链表通常需要创建头节点,并将指针初始化为NULL:
c
Node* createList() {
Node *head = (Node*)malloc(sizeof(Node));
if (head == NULL) {
printf("内存分配失败\n");
exit(1);
}
head->prev = NULL;
head->next = NULL;
return head;
}
四、插入节点
双向链表的插入操作分为头部插入、尾部插入和指定位置插入。
1、头部插入:
c
void insertAtHead(Node *head, int data) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->prev = NULL;
newNode->next = head->next;
if (head->next != NULL) {
head->next->prev = newNode;
}
head->next = newNode;
}
2、尾部插入:
c
void insertAtTail(Node *head, int data) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = NULL;
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
五、删除节点
删除操作需要调整前驱和后继节点的指针:
c
void deleteNode(Node *head, int data) {
Node *current = head->next;
while (current != NULL) {
if (current->data == data) {
if (current->prev != NULL) {
current->prev->next = current->next;
}
if (current->next != NULL) {
current->next->prev = current->prev;
}
free(current);
return;
}
current = current->next;
}
printf("未找到该节点\n");
}
六、遍历双向链表
双向链表支持正向和反向遍历:
1、正向遍历:
c
void traverseForward(Node *head) {
Node *current = head->next;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
2、反向遍历:
c
void traverseBackward(Node *head) {
Node *current = head;
while (current->next != NULL) {
current = current->next;
}
while (current != head) {
printf("%d ", current->data);
current = current->prev;
}
printf("\n");
}