📜  反转双向链表的 C 程序(1)

📅  最后修改于: 2023-12-03 14:50:35.990000             🧑  作者: Mango

反转双向链表的 C 程序

双向链表是一种常见的数据结构,其中每个节点除了一个指针指向下一个节点,还有一个指针指向前一个节点。常常需要在程序中对双向链表进行操作,其中一个常见的操作是反转双向链表。

本文介绍如何使用 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;
    }
}

该函数将链表中的每个节点的 prevnext 指针反转,并且在反转完成后更新头节点指向第一个节点的指针。需要注意的是,如果链表为空或只有一个节点,则无需反转。

在反转双向链表时,需要注意链表中指针的指向关系。建议在反转链表时使用一个临时指针,避免指针丢失。