C语言实现循环双链表

在C语言中,实现一个循环双链表需要定义一个节点结构体,这个结构体包含三个字段:数据字段,指向前一个节点的指针,以及指向下一个节点的指针。定义节点结构体:

1)定义节点结构体:

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

2)创建节点:创建一个新节点并初始化它的数据和指针。

Node* createNode(int data) {  
    Node* newNode = (Node*)malloc(sizeof(Node));  
    if (!newNode) {  
        printf("Memory error\n");  
        return NULL;  
    }  
    newNode->data = data;  
    newNode->next = NULL;  
    newNode->prev = NULL;  
    return newNode;  
}

3)插入节点:在链表的末尾添加一个新节点。需要考虑的是如何更新新节点和前一个节点的指针。

void insertNode(Node** head, int data) {  
    Node* newNode = createNode(data);  
    if (*head == NULL) { // 如果链表为空,新节点就是头节点  
        *head = newNode;  
        newNode->next = newNode;  
        newNode->prev = newNode;  
    } else { // 否则,将新节点添加到链表的末尾  
        Node* curr = *head;  
        while (curr->next != *head) { // 找到链表的末尾  
            curr = curr->next;  
        }  
        curr->next = newNode; // 更新末尾节点的next指针  
        newNode->prev = curr; // 更新新节点的prev指针  
        newNode->next = *head; // 新节点的next指针指向头节点  
        (*head)->prev = newNode; // 更新头节点的prev指针指向新节点  
    }  
}

 4)删除节点:删除一个指定的节点。需要考虑的是如何更新被删除节点的前后节点的指针,以及如何处理被删除节点是头节点的情况。

void deleteNode(Node** head, int data) {  
    Node* curr = *head;  
    if (*head == NULL) { // 如果链表为空,直接返回  
        return;  
    }  
    if (curr->data == data) { // 如果头节点就是要删除的节点  
        Node* temp = *head;  
        *head = (*head)->next; // 将头节点的next指针作为新的头节点  
        (*head)->prev = *head; // 新的头节点的prev指针指向自己  
        free(temp); // 释放旧的头节点内存空间  
        return;  
    }  
    while (curr->data != data) { // 找到要删除的节点  
        curr = curr->next;  
        if (curr == *head) { // 如果链表中没有找到要删除的节点,直接返回  
            return;  
        }  
    }  
    Node* temp = curr; // 保存要删除的节点的指针  
    curr = curr->next; // 将要删除节点的next指针作为当前节点  
    curr->prev = temp->prev; // 更新当前节点的prev指针指向要删除节点的prev指针所指向的节点  
    temp->prev->next = curr; // 更新要删除节点的prev指针所指向的节点的next指针指向当前节点  
    free(temp); // 释放要删除的节点的内存空间  
}

 5)打印链表:遍历链表并打印每个节点的数据。

void printList(Node* head) {  
    if (head == NULL) { // 如果链表为空,直接返回  
        printf("List is empty.\n");  
        return;  
    }  
    Node* curr = head; // 从头节点开始遍历链表  
    do { // 使用do-while循环,保证至少打印一次头节点的数据值,即使链表只有一个节点。注意使用前置++运算符。  
        printf("%d ", curr->data); // 打印当前节点的数据值,注意没有换行。使用后置++运算符。    } while ((curr = curr->next) != head); // 移动到下一个节点,如果当前节点是头节点,结束循环。注意使用前置++运算符。    printf("\n"); // 在打印完最后一个数据值后换行。 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全职编程-叶秋然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值