news 2025/12/28 4:01:33

不带头节点的循环双链表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
不带头节点的循环双链表

1.创建一个双链表的类型

typedef struct DLNode { int data; struct DLNode* prior, * next;//里面有两个指针,一个前驱指针,一个后驱指针 } DLNode, * DLinkList;//重新定义一个名字,DLNode是节点名字,DLinkList是双链条的名字,也是个指针

2.用创建好的结构体创建一个变量,进行初始化

int InitDLinkList(DLinkList*L) { (*L) = NULL;//把表头置为空 return 0; }

3.判断表是不是空表,因为有两个节点指针,判断节点指针是不是都为空即可

int Is_empty(DLinkList*L) { return((*L)->next == NULL) && ((*L)->prior == NULL);//只要两个节点都指向空说明这个链表没有数据 }

4.给定一个位序进行插入,因为不带头节点所以考虑的事情相对多,要考虑第一个元素可最后一个元素

int insertLocate(DLinkList* L, int i, int elem)//在位序为i处插入一个elem 的元素 { if (i < 0) { return 1; } if (i == 1) { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = elem; s->next = NULL; s->prior = NULL; (*L) = s; return 0; } int j = 1; DLNode* p = (*L);//将第一个元素付给p节点,就一个节点这个节点就是p while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL) { return 1;//i的值不合法 } DLNode* q = (DLNode*)malloc(sizeof(DLNode)); if (q == NULL) { return 1; } q->data = elem; q->next = p->next; if(p->next!=NULL)//如果等于就只需要链接三条线因为最后一个元素没有前驱指针 p->next->prior = q; p->next = q; q->prior = p; return 0; }

5.给定一个节点进行插入操作

int InsertDLNode(DLinkList* L, DLNode* p,DLNode*s, int elem)//在指定的节点p插入一个数据元素为elem的数据 { if (p == NULL) { return 1; } s->next = p->next;//插入到p节点的后面,然后交换p指针和q指针的值 if(p->next!=NULL) p->next->prior = s; p->next = s; s->prior = p; s->data = p->data; p->data = elem; return 0; }

6.给定一个值,查找这个值的位序

int GetLocate(DLinkList* L, int elem)//查找elem的位序 { DLNode* p = (*L); int count = 0; while (p) { count++; if (p->data == elem) { return count;//返回位序 } p = p->next; } return -1;//找不到返回-1

7.给定一个值,删除第一个相同的值

nt DeleteElem(DLinkList* L, int elem) { if ((*L)->data == elem) { DLNode* p = (*L)->next; (*L)->next->prior = (*L)->prior; free(*L); (*L) = p; } int pos=GetLocate(L, elem);//pos=位序 int j = 1; DLNode* p = (*L); while (p != NULL && j < pos - 1) { p = p->next; j++; } if (p == NULL) { return 0; } DLNode* ptr = p->next; p->next = ptr->next; if (ptr->next != NULL) ptr->next->prior = p; free(ptr); }

8.打印整个链表的数据

void Display(DLinkList* L) { DLNode* p = (*L); while (p!=NULL)//如果p等于NULL说明这个时候就是错误的,不会进入循环里面 { printf("%d-> ", p->data); p = p->next; } printf("NULL\n"); }

9.头插法建立双链表,头插法很重要,链表的逆置需要用到头插法

int HeadInsert(DLinkList* L)//头插法建立单链表 { int x = 0; scanf("%d", &x); DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; s->next = NULL; s->prior = NULL;//头插法建立双链表的时候先整一个头节点,逻辑上的头节点 (*L) = s; scanf("%d", &x); while (x)//x为零就结束建立 { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->next = (*L); (*L)->prior = s; s->data = x; (*L) = s; scanf("%d", &x); } return 0; }

10.尾插法建立单链表

int TailInsert(DLinkList* L) { int x = 0; scanf("%d", &x); DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; s->next = NULL; s->prior = NULL; (*L) = s; //(*L)->next = NULL; scanf("%d", &x); DLNode* tail = (*L);//把头节点赋值个头指针 while (x) { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; tail->next = s->next; s->prior = tail; tail->next = s; tail = s; scanf("%d", &x); } tail->next = NULL;//最后要把尾指针置为NULL return 0; }

11.总体代码

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> typedef struct DLNode { int data; struct DLNode* prior, * next;//里面有两个指针,一个前驱指针,一个后驱指针 } DLNode, * DLinkList;//重新定义一个名字,DLNode是节点名字,DLinkList是双链条的名字,也是个指针 int InitDLinkList(DLinkList*L) { (*L) = NULL;//把表头置为空 return 0; } int Is_empty(DLinkList*L) { return((*L)->next == NULL) && ((*L)->prior == NULL);//只要两个节点都指向空说明这个链表没有数据 } int InsertDLNode(DLinkList* L, DLNode* p,DLNode*s, int elem)//在指定的节点p插入一个数据元素为elem的数据 { if (p == NULL) { return 1; } s->next = p->next;//插入到p节点的后面,然后交换p指针和q指针的值 if(p->next!=NULL) p->next->prior = s; p->next = s; s->prior = p; s->data = p->data; p->data = elem; return 0; } int insertLocate(DLinkList* L, int i, int elem)//在位序为i处插入一个elem 的元素 { if (i < 0) { return 1; } if (i == 1) { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = elem; s->next = NULL; s->prior = NULL; (*L) = s; return 0; } int j = 1; DLNode* p = (*L);//将第一个元素付给p节点,就一个节点这个节点就是p while (p != NULL && j < i - 1) { p = p->next; j++; } if (p == NULL) { return 1;//i的值不合法 } DLNode* q = (DLNode*)malloc(sizeof(DLNode)); if (q == NULL) { return 1; } q->data = elem; q->next = p->next; if(p->next!=NULL)//如果等于就只需要链接三条线因为最后一个元素没有前驱指针 p->next->prior = q; p->next = q; q->prior = p; return 0; } int GetLocate(DLinkList* L, int elem)//查找elem的位序 { DLNode* p = (*L); int count = 0; while (p) { count++; if (p->data == elem) { return count;//返回位序 } p = p->next; } return -1;//找不到返回-1 } int DeleteElem(DLinkList* L, int elem) { if ((*L)->data == elem) { DLNode* p = (*L)->next; (*L)->next->prior = (*L)->prior; free(*L); (*L) = p; } int pos=GetLocate(L, elem);//pos=位序 int j = 1; DLNode* p = (*L); while (p != NULL && j < pos - 1) { p = p->next; j++; } if (p == NULL) { return 0; } DLNode* ptr = p->next; p->next = ptr->next; if (ptr->next != NULL) ptr->next->prior = p; free(ptr); } void Display(DLinkList* L) { DLNode* p = (*L); while (p!=NULL)//如果p等于NULL说明这个时候就是错误的,不会进入循环里面 { printf("%d-> ", p->data); p = p->next; } printf("NULL\n"); } int HeadInsert(DLinkList* L)//头插法建立单链表 { int x = 0; scanf("%d", &x); DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; s->next = NULL; s->prior = NULL;//头插法建立双链表的时候先整一个头节点,逻辑上的头节点 (*L) = s; scanf("%d", &x); while (x)//x为零就结束建立 { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->next = (*L); (*L)->prior = s; s->data = x; (*L) = s; scanf("%d", &x); } return 0; } int TailInsert(DLinkList* L) { int x = 0; scanf("%d", &x); DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; s->next = NULL; s->prior = NULL; (*L) = s; //(*L)->next = NULL; scanf("%d", &x); DLNode* tail = (*L);//把头节点赋值个头指针 while (x) { DLNode* s = (DLNode*)malloc(sizeof(DLNode)); if (s == NULL) { return 1; } s->data = x; tail->next = s->next; s->prior = tail; tail->next = s; tail = s; scanf("%d", &x); } tail->next = NULL;//最后要把尾指针置为NULL return 0; } int main() { DLinkList L; InitDLinkList(&L); /*insertLocate(&L, 1, 2); insertLocate(&L, 2, 3); insertLocate(&L, 3, 4); insertLocate(&L, 4, 5); insertLocate(&L, 5, 6);*/ TailInsert(&L); //insertLocate(&L, 6, 7); //DeleteElem(&L,7); //DeleteElem(&L, 7); int ret=Is_empty(&L); if (ret) { printf("空\n"); } else { printf("非空\n"); } Display(&L); int pos = GetLocate(&L, 6); printf("%d\n",pos);// return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/27 13:29:38

V助手舆情分析智能体:重塑舆情分析,从“人找信息”到“信息为人”

V助手舆情分析智能体&#xff1a;重塑舆情分析&#xff0c;从“人找信息”到“信息为人”在信息爆炸的时代&#xff0c;舆情分析工作常常面临数据繁杂、流程冗长、响应迟缓等挑战。传统方式不仅耗时耗力&#xff0c;更易错失关键信息与应对先机。如今&#xff0c;随着蜜度V助手…

作者头像 李华
网站建设 2025/12/25 10:42:30

连接2026:十款远程控制软件真实力横评与选择指南

目录引&#x1f4c8; 选择前必读&#xff1a;明确你的核心需求&#x1f3c6; 综合王者&#xff1a;ToDesk&#xff08;评分 9.6/10&#xff09;&#x1f3af; 细分领域佼佼者&#x1f3ae; 为游戏而生&#xff1a;网易UU远程&#xff08;评分 8.4/10&#xff09;&#x1f3ac; …

作者头像 李华
网站建设 2025/12/27 21:41:33

计算机毕业设计springboot基于Spark++Vue.js的学生管理系统 Spark+Vue 高校学生综合信息管理平台 基于 SpringBoot+Spark+Vue 的全链路学生事务中心

计算机毕业设计springboot基于SparkVue.js的学生管理系统i2kn7p36 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。在“数据即资产”的校园时代&#xff0c;传统 Excel 与人工流转…

作者头像 李华
网站建设 2025/12/27 14:52:12

为什么 C盘空间会莫名其妙减少(即使没装新软件)?

为什么 C盘空间会莫名其妙减少&#xff08;即使没装新软件&#xff09;&#xff1f;你有没有注意到c盘空间在减少&#xff0c;即使你没有安装新程序, 这个常见问题可能让人担心, 但通常有明确原因, windows和其他软件会定期创建临时文件、系统备份和更新, 占用磁盘空间而不会每…

作者头像 李华