当前位置: 首页 > news >正文

c语言数据结构 双循环链表设计(完整代码)

双循环链表设计

1.创建结构双指针体

// 创建结构体
struct node
{
    struct node *prev; // 前驱节点
    int data;          // 数据域
    struct node *next;
};

2.创建/增加节点,使用malloc函数来位节点分配空间,并初始化接节点

// 节点初始化
struct node *create_node(int data)
{
    struct node *xnew = malloc(sizeof(struct node));
    if (xnew == NULL)
    {
        perror("创建失败\n");
    }
    xnew->prev = xnew;
    xnew->data = data;
    xnew->next = xnew;
    return xnew;
}

3.头插法插入节点,先让新的节点链接到头节点,若有2个节点存在的情况下,就让新节点先链接头节点跟头节点的下一个节点。

// 头插法
void tou(struct node *head, struct node *xnew)
{
    xnew->prev = head;
    xnew->next = head->next;
    head->next->prev = xnew;
    head->next = xnew;
}

4.尾插法,因为时双链表所以我们不定义游走指针,我们直接用头节点的prev指针指向最后一个节点,并让最后一个节点跟新节点链接。

// 尾插法
void wei(struct node *head, struct node *xnew)
{
    xnew->next = head;
    xnew->prev = head->prev;
    head->prev->next = xnew; // 这句要先写,否则会导致原先的指针被覆盖掉
    head->prev = xnew;
}

5.显示的前遍历,通过定义一个结构体指针pre,让其指向最后一个节点,再通过访问节点不断的偏移,使用pre = pre->prev来访问节点

// 前遍历
void show_qian(struct node *head)
{
    struct node *pre = head->prev;
    printf("前遍历:");
    while (pre != head)
    {
        printf("%d ", pre->data);
        pre = pre->prev;
    }
    printf("\n");
}

6.显示的后遍历,通过定义一个结构体指针pos,让其指向第一个节点,再通过偏移pos指针,让其不断地走,pos = pos->next,与前遍历一样判断的条件都是指针不等于头节点。

// 后遍历
void show_hou(struct node *head)
{
    struct node *pos = head->next;
    printf("后遍历:");
    while (pos != head)
    {
        printf("%d ", pos->data);
        pos = pos->next;
    }

    printf("\n");
}

7.删除双循环链表的节点, 先定义一个结构体指针pos指向头结点的下一位,通过while循环来找到数据后,我们定义一个结构体指针p,指向当前这个数据的地址,并让指针pos重新链接到p的下一位,然后让结构体指针p的双指针都指向NULL,然后free(p);

//删除双循环链表的节点
void delete_node(struct node *head,int data)
{
    struct node *pos = head->next;
    while(pos->data != data)
    {
        pos = pos->next;
    }
    struct node *p = pos;
    pos = pos->prev;
    pos->next = p->next;
    p->next->prev = pos;
    p->next = NULL;
    p->prev = NULL;
    free(p);
}

8.修改节点,跟单循环链表的修该节点方式一样,不过双链表可以从后面或者前面来遍历并找到数组,定义一个游走的结构体指针pos,让其不断地访问节点的数值,如果不是那么就往下一位走,直到找到数据,找到数据后重新赋值新数值。

//修改双链表的节点数据
void modify_node(struct node *head,int  data, int new_data)
{
    struct node *pos = head->next;
    while(pos->data != data)
    {
        pos = pos->next;//pos指针不断移动去比对
    }
    pos->data = new_data;
}

完整代码:

#include <stdio.h>
#include <stdlib.h>
// 双循环链表

// 创建结构体
struct node
{
    struct node *prev; // 前驱节点
    int data;          // 数据域
    struct node *next;
};

// 节点初始化
struct node *create_node(int data)
{
    struct node *xnew = malloc(sizeof(struct node));
    if (xnew == NULL)
    {
        perror("创建失败\n");
    }
    xnew->prev = xnew;
    xnew->data = data;
    xnew->next = xnew;
    return xnew;
}
// 头插法
void tou(struct node *head, struct node *xnew)
{
    xnew->prev = head;
    xnew->next = head->next;
    head->next->prev = xnew;
    head->next = xnew;
}
// 尾插法
void wei(struct node *head, struct node *xnew)
{
    xnew->next = head;
    xnew->prev = head->prev;
    head->prev->next = xnew; // 这句要先写,否则会导致原先的指针被覆盖掉
    head->prev = xnew;
}

// 前遍历
void show_qian(struct node *head)
{
    struct node *pre = head->prev;
    printf("前遍历:");
    while (pre != head)
    {
        printf("%d ", pre->data);
        pre = pre->prev;
    }
    printf("\n");
}
// 后遍历
void show_hou(struct node *head)
{
    struct node *pos = head->next;
    printf("后遍历:");
    while (pos != head)
    {
        printf("%d ", pos->data);
        pos = pos->next;
    }

    printf("\n");
}

//删除双循环链表的节点
void delete_node(struct node *head,int data)
{
    struct node *pos = head->next;
    while(pos->data != data)
    {
        pos = pos->next;
    }
    struct node *p = pos;
    pos = pos->prev;
    pos->next = p->next;
    p->next->prev = pos;
    p->next = NULL;
    p->prev = NULL;
    free(p);
}

//修改双链表的节点数据
void modify_node(struct node *head,int  data, int new_data)
{
    struct node *pos = head->next;
    while(pos->data != data)
    {
        pos = pos->next;//pos指针不断移动去比对
    }
    pos->data = new_data;
}
int main()
{
    struct node *head = create_node(0);
    for (int i = 1; i < 10; i++)
    {
        // tou(head, create_node(i));
        wei(head, create_node(i));
    }
    show_qian(head); // 前遍历
    show_hou(head);  // 后遍历
    delete_node(head,5);
    show_qian(head); // 前遍历
    show_hou(head);  // 后遍历
    modify_node(head,2,666);
    show_qian(head); // 前遍历
    show_hou(head);  // 后遍历
}

相关文章:

  • Ubuntu版免翻墙搭建BatteryHistorian
  • freeswitch(开启抓包信息)
  • 观察RenderDoc截帧UE时“Event”代表什么
  • ssh 多重验证的好处:降低密钥长度,动态密码
  • 分布式任务调度
  • 事件响应计划:网络弹性的关键
  • C++ :try 语句块和异常处理
  • IDEA批量替换项目下所有文件中的特定内容
  • Python Cookbook-4.7 在行列表中完成对列的删除和排序
  • 主流加固方案深度剖析(梆梆/腾讯/阿里)
  • 《数据库原理教程》—— 第三章 关系数据模型 笔记
  • 解释 RESTful API,以及如何使用它构建 web 应用程序
  • Linux驱动开发实战(七):pinctrl引脚管理入门结合数据手册分析
  • Powershell WSL导出导入ubuntu22.04.5子系统
  • 1.5.5 掌握Scala内建控制结构 - 异常处理
  • 编写脚本在Linux下启动、停止SpringBoot工程
  • 强大的AI网站推荐(第一集)—— Devv AI
  • 串口部分问题
  • 21、web前端开发之html5(二)
  • Deepseek+飞书实现简历分析建议+面试题
  • 简单手机网站如何制作/上海做推广的引流公司
  • 杭州做企业网站/百度贴吧热线客服24小时
  • 北京网站开发哪家好/谷歌seo服务
  • 如何部署asp网站/黑科技引流推广神器免费
  • 想做个自己的网站/广州网站建设系统
  • redis网站开发书籍/seo网站推广排名