• C语言实现循环双链表


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

    1)定义节点结构体

    1. typedef struct Node {
    2. int data;
    3. struct Node* prev;
    4. struct Node* next;
    5. } Node;

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

    1. Node* createNode(int data) {
    2. Node* newNode = (Node*)malloc(sizeof(Node));
    3. if (!newNode) {
    4. printf("Memory error\n");
    5. return NULL;
    6. }
    7. newNode->data = data;
    8. newNode->next = NULL;
    9. newNode->prev = NULL;
    10. return newNode;
    11. }

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

    1. void insertNode(Node** head, int data) {
    2. Node* newNode = createNode(data);
    3. if (*head == NULL) { // 如果链表为空,新节点就是头节点
    4. *head = newNode;
    5. newNode->next = newNode;
    6. newNode->prev = newNode;
    7. } else { // 否则,将新节点添加到链表的末尾
    8. Node* curr = *head;
    9. while (curr->next != *head) { // 找到链表的末尾
    10. curr = curr->next;
    11. }
    12. curr->next = newNode; // 更新末尾节点的next指针
    13. newNode->prev = curr; // 更新新节点的prev指针
    14. newNode->next = *head; // 新节点的next指针指向头节点
    15. (*head)->prev = newNode; // 更新头节点的prev指针指向新节点
    16. }
    17. }

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

    1. void deleteNode(Node** head, int data) {
    2. Node* curr = *head;
    3. if (*head == NULL) { // 如果链表为空,直接返回
    4. return;
    5. }
    6. if (curr->data == data) { // 如果头节点就是要删除的节点
    7. Node* temp = *head;
    8. *head = (*head)->next; // 将头节点的next指针作为新的头节点
    9. (*head)->prev = *head; // 新的头节点的prev指针指向自己
    10. free(temp); // 释放旧的头节点内存空间
    11. return;
    12. }
    13. while (curr->data != data) { // 找到要删除的节点
    14. curr = curr->next;
    15. if (curr == *head) { // 如果链表中没有找到要删除的节点,直接返回
    16. return;
    17. }
    18. }
    19. Node* temp = curr; // 保存要删除的节点的指针
    20. curr = curr->next; // 将要删除节点的next指针作为当前节点
    21. curr->prev = temp->prev; // 更新当前节点的prev指针指向要删除节点的prev指针所指向的节点
    22. temp->prev->next = curr; // 更新要删除节点的prev指针所指向的节点的next指针指向当前节点
    23. free(temp); // 释放要删除的节点的内存空间
    24. }

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

    1. void printList(Node* head) {
    2. if (head == NULL) { // 如果链表为空,直接返回
    3. printf("List is empty.\n");
    4. return;
    5. }
    6. Node* curr = head; // 从头节点开始遍历链表
    7. do { // 使用do-while循环,保证至少打印一次头节点的数据值,即使链表只有一个节点。注意使用前置++运算符。
    8. printf("%d ", curr->data); // 打印当前节点的数据值,注意没有换行。使用后置++运算符。 } while ((curr = curr->next) != head); // 移动到下一个节点,如果当前节点是头节点,结束循环。注意使用前置++运算符。 printf("\n"); // 在打印完最后一个数据值后换行。
  • 相关阅读:
    进程间通信(IPC):共享内存
    Chatgpt人工智能对话源码系统分享 带完整搭建教程
    uniapp微信公众号跳转到小程序(是点击微信页面上面的按钮/菜单跳转)
    【计算机毕业设计】基于JAVA的在线租房网站系统源码
    在vue3的开发环境中为什么使用vite而不是用webpack
    Flutter 学习笔记(01)__从 0 开始创建一个 flutter 项目
    单例模式之懒汉式和饿汉式
    RIP协议详解及快速学会RIP
    Ubuntu 22.04 桌面美化成Mac风格
    JavaScript基础05——字面量、变量介绍及变量基本使用
  • 原文地址:https://blog.csdn.net/MyLovelyJay/article/details/133189150