📅  最后修改于: 2023-12-03 14:50:35.990000             🧑  作者: Mango
双向链表是一种常见的数据结构,其中每个节点除了一个指针指向下一个节点,还有一个指针指向前一个节点。常常需要在程序中对双向链表进行操作,其中一个常见的操作是反转双向链表。
本文介绍如何使用 C 语言编写一个反转双向链表的程序。下面的程序实现了一个具有头结点的双向链表的反转。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
struct Node* prev;
} Node;
void printList(Node* head) {
if (head == NULL) {
printf("The list is empty.\n");
return;
}
Node* curr = head->next;
printf("List contents: ");
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
printf("\n");
}
void insert(Node* head, int data) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = data;
new_node->next = head->next;
new_node->prev = head;
if (head->next != NULL) {
head->next->prev = new_node;
}
head->next = new_node;
}
void reverseList(Node* head) {
if (head == NULL || head->next == NULL) {
return;
}
Node* curr = head->next;
Node* temp = NULL;
while (curr != NULL) {
temp = curr->prev;
curr->prev = curr->next;
curr->next = temp;
curr = curr->prev;
}
if (temp != NULL) {
head->next = temp->prev;
}
}
int main() {
Node* head = (Node*)malloc(sizeof(Node));
head->data = -1;
head->next = NULL;
head->prev = NULL;
for (int i = 0; i < 10; i++) {
insert(head, i);
}
printf("Before reversing:\n");
printList(head);
reverseList(head);
printf("After reversing:\n");
printList(head);
return 0;
}
上述代码使用了 typedef
关键字将 struct Node
声明为一个名为 Node
的类型。在 printList
函数中,首先判断链表是否为空,然后从头节点的下一节点开始遍历链表,输出节点的数据。insert
函数在链表的头部插入一个新节点,reverseList
函数将链表反转。在 main
函数中,创建了一个具有头结点的链表,并插入 10 个节点。然后输出反转前后的链表。
反转双向链表的核心代码如下:
void reverseList(Node* head) {
if (head == NULL || head->next == NULL) {
return;
}
Node* curr = head->next;
Node* temp = NULL;
while (curr != NULL) {
temp = curr->prev;
curr->prev = curr->next;
curr->next = temp;
curr = curr->prev;
}
if (temp != NULL) {
head->next = temp->prev;
}
}
该函数将链表中的每个节点的 prev
和 next
指针反转,并且在反转完成后更新头节点指向第一个节点的指针。需要注意的是,如果链表为空或只有一个节点,则无需反转。
在反转双向链表时,需要注意链表中指针的指向关系。建议在反转链表时使用一个临时指针,避免指针丢失。