当前位置:   article > 正文

【数据结构】单链表的基本操作 (C语言版)_c语言单链表基本操作

c语言单链表基本操作

目录

一、单链表

1、单链表的定义:

2、单链表的优缺点:

二、单链表的基本操作算法(C语言)

1、宏定义

2、创建结构体

3、初始化

4、插入

4、求长度

5、清空

6、销毁 

7、取值

8、查找

9、删除

10、头插法创建单链表

11、尾插法创建单链表

三、单链表的全部代码(C语言)

四、运行结果


一、单链表

1、单链表的定义:

 单链表是一种链式存储的线性表,它用一组地址任意的存储单元来存放线性表中的数据元素。每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素,指针域则存储下一个节点的地址。单链表的第一个节点称为头结点,最后一个节点称为尾结点。

单链表是一种链式存取的数据结构,用一组地址任意的存储单元来存放线性表中的数据元素。

每个节点包含两个部分:数据域和指针域。数据域用于存储数据元素,指针域则存储下一个节点的地址。链表中的数据是以结点来表示的,每个结点的构成包括元素(数据元素的映像)和指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。链表中的每个结点在内存中不是按顺序排列的,而是通过指针链接在一起。单链表的第一个节点称为头结点,最后一个节点称为尾结点。

与顺序表相比,单链表的优点在于插入和删除操作方便,时间复杂度较低,但随机访问和空间利用率不如顺序表。在实际应用中,单链表通常作为其他数据结构的子结构,如哈希表的桶、图的邻接表等。

单链表定义了节点的基本结构,包括数据元素和指向下一个节点的指针。节点的插入和删除操作涉及指针的修改,而非直接修改节点内容。由于其非连续性的特性,链表无法像数组一样随机访问任意元素,而只能从头到尾依次访问。因此,对于需要频繁插入和删除元素的应用场景,单链表是一种高效的数据结构。

2、单链表的优缺点:

单链表的优点:

  1. 插入和删除操作方便:只需修改指针即可,不需要移动大量元素。
  2. 动态分配内存:可以根据需要开辟内存空间,避免了顺序表中的空间浪费问题。

单链表的缺点:

  1. 存储密度低:以节点为单位存储,不支持随机访问,查找较为麻烦。
  2. 空间利用率低:每个节点需要额外的空间来存储指针,导致空间浪费。
  3. 查找效率低:由于链表在内存中不连续,需要从头节点开始逐个节点遍历,时间复杂度较高。

二、单链表的基本操作算法(C语言)

1、宏定义
  1. #define OK 1
  2. #define ERROR 0
  3. typedef char ElemType;
  4. typedef int Status;
2、创建结构体
  1. typedef struct LNode{
  2. ElemType data;
  3. struct LNode *next;
  4. }LNode,*LinkList;
3、初始化
  1. //单链表初始化
  2. Status InitList(LinkList &head){
  3. head=new LNode;
  4. head->next=NULL;
  5. return OK;
  6. }
4、插入
  1. 创建一个新的结点。
  2. 将新结点的数据域置为所需插入的数据。
  3. 根据插入位置的不同,将新结点的指针域指向插入位置的后一个结点。如果是头部插入,则将新结点的指针域指向头结点;如果是尾部插入,则将新结点的指针域指向空;如果是中间插入,则将新结点的指针域指向插入位置的后一个结点。
  4. 将插入位置前一个结点的指针域修改为指向新结点。如果是头部插入,则将头结点的指针域修改为指向新结点;如果是尾部插入,则将尾结点的指针域修改为指向新结点;如果是中间插入,则将插入位置前一个结点的指针域修改为指向新结点。
  1. //插入
  2. Status ListInsert(LinkList &head,int i,ElemType e){
  3. LinkList p=head;
  4. int j=0;
  5. while (p && (j<i-1)){
  6. p=p->next;
  7. ++j;
  8. }
  9. if (!p||j>i-1){
  10. return ERROR;
  11. }
  12. LNode *s=new LNode;
  13. s->data=e;
  14. s->next=p->next;
  15. p->next=s;
  16. return OK;
  17. }
4、求长度
  1. //求单链表长度
  2. Status GetLinkListLength(LinkList head){
  3. LinkList p=head->next;
  4. int length=0;
  5. while (p){
  6. p=p->next;
  7. length++;
  8. }
  9. return length;
  10. }
5、清空
  1. //清空
  2. Status ClearLinkList(LinkList &head){
  3. LinkList p = head->next;
  4. LinkList q;
  5. while(p){
  6. q = p;
  7. p = p->next;
  8. delete q;
  9. }
  10. head->next = NULL;
  11. return OK;
  12. }
6、销毁 
  1. //销毁
  2. Status DestoryLinkList(LinkList &head){
  3. LinkList p;
  4. while(head){
  5. p = head;
  6. head = head->next;
  7. delete p;
  8. }
  9. return OK;
  10. }
7、取值
  1. //取值
  2. Status GetLinkList(LinkList head,int i,ElemType &e){
  3. LinkList p = head->next;
  4. int j = 0;
  5. while (p && j<i){
  6. p=p->next;
  7. j++;
  8. }
  9. if (!p || j>i){
  10. return ERROR;
  11. }
  12. e=p->data;
  13. return OK;
  14. }
8、查找
  1. //查找用函数返回查找元素的位置
  2. int LocateLinkListElem(LinkList head,ElemType e){
  3. LinkList p=head->next;
  4. int j=1;
  5. while (p && (p->data != e)){
  6. p=p->next;
  7. j++;
  8. }
  9. if(p==NULL){
  10. return 0;
  11. }
  12. return j;
  13. }
9、删除
  1. 找到要删除的结点的前一个结点。
  2. 将前一个结点的指针域修改为指向要删除的结点的下一个结点。
  3. 释放要删除的结点的存储空间。
  1. //删除
  2. Status ListDelete(LinkList &head,int i,ElemType &e){
  3. LinkList p=head;
  4. int j=0;
  5. while ((p->next) && (j<i-1)){
  6. p=p->next;
  7. ++j;
  8. }
  9. if (!(p->next)||j>i-1){
  10. return ERROR;
  11. }
  12. LinkList q=p->next;
  13. e=q->data;
  14. p->next=q->next;
  15. delete q;
  16. return OK;
  17. }
10、头插法创建单链表
  1. //头插法创建单链表
  2. void CreateList_H(LinkList &head,int n){
  3. head=new LNode;
  4. head->next=NULL;
  5. for(int i=0;i<n;++i){
  6. LNode *p=new LNode;
  7. ElemType cin='a';
  8. cin>>p->data;
  9. p->next=head->next;
  10. head->next=p;
  11. }
  12. }
11、尾插法创建单链表
  1. //尾插法创建单链表
  2. void CreateList_R(LinkList &head,int n){
  3. head=new LNode;
  4. head->next=NULL;
  5. LNode *r=head;
  6. for(int i=0;i<n;++i){
  7. LNode *p=new LNode;
  8. ElemType cin='a';
  9. cin>>p->data;
  10. p->next=NULL;
  11. r->next=p;
  12. r=p;
  13. }
  14. }

三、单链表的全部代码(C语言)

  1. #include <stdio.h>
  2. #define OK 1
  3. #define ERROR 0
  4. typedef char ElemType;
  5. typedef int Status;
  6. typedef struct LNode{
  7. ElemType data;
  8. struct LNode *next;
  9. }LNode,*LinkList;
  10. //单链表初始化
  11. Status InitList(LinkList &head){
  12. head=new LNode;
  13. head->next=NULL;
  14. return OK;
  15. }
  16. //功能菜单
  17. int choice() {
  18. printf("==================================\n");
  19. printf(" 单链表操作功能菜单 \n");
  20. printf("1、插入元素 2、查询表长 3、按位查找\n");
  21. printf("4、按值查找 5、删除元素 6、销毁链表\n");
  22. printf("7、清空链表 8、批量插入 9、结束程序\n");
  23. printf("10、头插法创建单链表11、尾插法创建单链表\n");
  24. printf("==================================\n");
  25. return 0;
  26. }
  27. //插入
  28. Status ListInsert(LinkList &head,int i,ElemType e){
  29. LinkList p=head;
  30. int j=0;
  31. while (p && (j<i-1)){
  32. p=p->next;
  33. ++j;
  34. }
  35. if (!p||j>i-1){
  36. return ERROR;
  37. }
  38. LNode *s=new LNode;
  39. s->data=e;
  40. s->next=p->next;
  41. p->next=s;
  42. return OK;
  43. }
  44. //求单链表长度
  45. Status GetLinkListLength(LinkList head){
  46. LinkList p=head->next;
  47. int length=0;
  48. while (p){
  49. p=p->next;
  50. length++;
  51. }
  52. return length;
  53. }
  54. //销毁
  55. Status DestoryLinkList(LinkList &head){
  56. LinkList p;
  57. while(head){
  58. p = head;
  59. head = head->next;
  60. delete p;
  61. }
  62. return OK;
  63. }
  64. //清空
  65. Status ClearLinkList(LinkList &head){
  66. LinkList p = head->next;
  67. LinkList q;
  68. while(p){
  69. q = p;
  70. p = p->next;
  71. delete q;
  72. }
  73. head->next = NULL;
  74. return OK;
  75. }
  76. //取值
  77. Status GetLinkList(LinkList head,int i,ElemType &e){
  78. LinkList p = head->next;
  79. int j = 0;
  80. while (p && j<i){
  81. p=p->next;
  82. j++;
  83. }
  84. if (!p || j>i){
  85. return ERROR;
  86. }
  87. e=p->data;
  88. return OK;
  89. }
  90. //查找用引用型参数返回查找元素的位置
  91. //LNode *LocateLinkList(LinkList head,ElemType e,Status &j){
  92. // LinkList p=head->next;
  93. // j=1;
  94. // while (p && p->data!=e){
  95. // p=p->next;
  96. // j++;
  97. // }
  98. // return p;
  99. //}
  100. //查找用函数返回查找元素的位置
  101. int LocateLinkListElem(LinkList head,ElemType e){
  102. LinkList p=head->next;
  103. int j=1;
  104. while (p && (p->data != e)){
  105. p=p->next;
  106. j++;
  107. }
  108. if(p==NULL){
  109. return 0;
  110. }
  111. return j;
  112. }
  113. //删除
  114. Status ListDelete(LinkList &head,int i,ElemType &e){
  115. LinkList p=head;
  116. int j=0;
  117. while ((p->next) && (j<i-1)){
  118. p=p->next;
  119. ++j;
  120. }
  121. if (!(p->next)||j>i-1){
  122. return ERROR;
  123. }
  124. LinkList q=p->next;
  125. e=q->data;
  126. p->next=q->next;
  127. delete q;
  128. return OK;
  129. }
  130. //头插法创建单链表
  131. void CreateList_H(LinkList &head,int n){
  132. head=new LNode;
  133. head->next=NULL;
  134. for(int i=0;i<n;++i){
  135. LNode *p=new LNode;
  136. ElemType cin='a';
  137. cin>>p->data;
  138. p->next=head->next;
  139. head->next=p;
  140. }
  141. }
  142. //尾插法创建单链表
  143. void CreateList_R(LinkList &head,int n){
  144. head=new LNode;
  145. head->next=NULL;
  146. LNode *r=head;
  147. for(int i=0;i<n;++i){
  148. LNode *p=new LNode;
  149. ElemType cin='a';
  150. cin>>p->data;
  151. p->next=NULL;
  152. r->next=p;
  153. r=p;
  154. }
  155. }
  156. int main()
  157. {
  158. LinkList list;
  159. //初始化
  160. printf("单链表正在初始化....\n");
  161. int InitStatus=InitList(list);
  162. if (InitStatus=OK){
  163. printf("单链表初始化成功!\n");
  164. }else{
  165. printf("单链表初始化失败!\n");
  166. }
  167. choice(); //调用功能菜单函数
  168. int temp=1; //通过改变temp的值来跳出while循环
  169. while(temp) {
  170. int flag;
  171. printf("请输入所需的功能编号:\n");
  172. scanf("%d",&flag);
  173. switch (flag) {//通过开关进行功能选择
  174. case 1:{//插入元素
  175. int insertIndex;
  176. ElemType inserElem;
  177. printf("请输入插入元素位置及插入元素(请在英文状态下输入): \n");
  178. scanf("%d,%c",&insertIndex,&inserElem);
  179. Status InsertS = ListInsert(list, insertIndex, inserElem);
  180. if(InsertS ==OK){
  181. printf("向单链表%d个位置,插入元素为%c成功!\n",insertIndex,inserElem);
  182. printf("======================================\n\n");
  183. }else{
  184. printf("向单链表插入元素失败!\n");
  185. printf("======================================\n\n");
  186. }
  187. }
  188. break;
  189. case 2:{//求单链表的长度
  190. int length=GetLinkListLength(list);
  191. printf("单链表的长度为:%d。 \n",length);
  192. }
  193. break;
  194. case 3:{//取值
  195. Status GetIndex;
  196. printf("请输入需要查询的元素的位置:\n");
  197. scanf("%d",&GetIndex);
  198. ElemType GetElem;
  199. int GetStatus=GetLinkList(list,GetIndex, GetElem);
  200. if (GetStatus=OK){
  201. printf("从单链表中获取第%d位置元素成功,所获取到的元素为:%c。\n",GetIndex,GetElem);
  202. }else{
  203. printf("从单链表中获取第%d位置元素失败!\n",GetIndex);
  204. }
  205. }
  206. break;
  207. case 4:{//查找
  208. //查找用引用型参数返回查找元素的位置
  209. // Status LocateIndex;
  210. // ElemType LocateElem;
  211. // printf("请输入想要查找元素:\n");
  212. // scanf("%c",&LocateElem);
  213. // LNode *LocateStatus = LocateLinkList(list,LocateElem,LocateIndex);
  214. // //printf("%d",LocateStatus);
  215. // if (LocateStatus == NULL) {
  216. // printf("未查找到需要查找元素!\n");
  217. // } else {
  218. // printf("查找到单链表中第%d元素为%c!\n",LocateIndex, LocateStatus->data);
  219. // }
  220. //查找用函数返回查找元素的位置
  221. ElemType LocateElem;
  222. printf("请输入想要查找元素:\n");
  223. getchar(); //用于接收回车
  224. scanf("%c",&LocateElem);
  225. Status LocateIndex = LocateLinkListElem(list,LocateElem);
  226. if (LocateIndex > 0) {
  227. printf("从单链表中查找元素%c成功,它在单链表中的位置为第%d个!\n",LocateElem,LocateIndex);
  228. } else {
  229. printf("从单链表中查找元素%c失败!\n",LocateElem);
  230. }
  231. }
  232. break;
  233. case 5:{//删除
  234. Status DeleteIndex;
  235. printf("请输入想要删除元素的位置:\n");
  236. scanf("%d",&DeleteIndex);
  237. ElemType DeleteElem;
  238. ElemType DeleteStatus = ListDelete(list,DeleteIndex,DeleteElem);
  239. if (DeleteStatus=OK){
  240. printf("删除单链表第%d个位置的元素成功,删除的元素为:%c。\n",DeleteIndex,DeleteElem);
  241. }else{
  242. printf("删除单链表第%d个位置的元素失败!\n",DeleteIndex);
  243. }
  244. }
  245. break;
  246. case 6:{//销毁
  247. Status DestoryStatus = DestoryLinkList(list);
  248. if (DestoryStatus == OK){
  249. printf("单链表销毁成功!\n");
  250. }else{
  251. printf("单链表销毁失败!\n");
  252. }
  253. }
  254. break;
  255. case 7:{//清空
  256. Status ClearStatus = ClearLinkList(list);
  257. if (ClearStatus == OK){
  258. printf("单链表清空成功!\n");
  259. }else{
  260. printf("单链表清空失败!\n");
  261. }
  262. }
  263. break;
  264. case 8:{//批量插入
  265. int on;
  266. printf("请输入想要插入的元素个数:\n");
  267. scanf("%d", &on);
  268. ElemType array[on];
  269. for (int i = 1; i <= on; i++) {
  270. getchar();
  271. printf("向单链表第%d个位置插入元素为:", (i));
  272. scanf("%c", &array[i]);
  273. }
  274. for (int i = 1; i <= on; i++){
  275. Status InsertStatus = ListInsert(list,i,array[i]);
  276. if (InsertStatus=OK){
  277. printf("向单链表第%d个位置插入元素%c成功!\n",i,array[i]);
  278. }else{
  279. printf("向单链表第%d个位置插入元素%c失败!\n",i,array[i]);
  280. }
  281. }
  282. }
  283. break;
  284. case 9:{//退出程序
  285. temp=0;
  286. // return 0;
  287. }
  288. break;
  289. case 10:{//头插法创建单链表
  290. // ElemType EnterElement='e';
  291. // CreateList_H(list,EnterElement);
  292. // printf("前插法插入%c元素成功!\n",EnterElement);
  293. }
  294. break;
  295. case 11:{//尾插法创建单链表
  296. // ElemType EnterElem='a';
  297. // CreateList_R(list,EnterElem);
  298. // printf("后插法插入%c元素成功!\n",EnterElem);
  299. }
  300. break;
  301. default:
  302. printf("输入错误,无此功能,请检查输入:\n");
  303. }
  304. }
  305. }

四、运行结果

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/636515
推荐阅读
相关标签
  

闽ICP备14008679号