当前位置:   article > 正文

C语言实现链表基本操作_c语言链表的基本操作

c语言链表的基本操作

目录

一、什么是链表

二、为什么要使用链表

三、链表相关知识

四、链表实现

1.定义结构体

2.创建链表

3.遍历链表

4.判断链表是否为空

5.计算链表长度

6.插入一个数据

7.删除数据

8.全部代码


一、什么是链表

如果把数据比喻成珠子,指针就是线,链表通过指针这条线就是把数据这些珠子串起来。

二、为什么要使用链表

数组是我们接触c语言时学到的一种重要的数据存储方式,是连续的,可以快速查找某个位置的数据。都是要对数组实现删除和插入等功能时,需要移动大量的数据,耗时长。而且数组使用前就分配好内存,分配的内存过小可能不够用,过大就造成浪费。

而链表实现对数据删除和插入的功能时具有优势,而且可以要用时才分配,可以说基本不存在内存不足和浪费的情况。链表分配内存时一小块一小块的,数组则是连续的一大块。假如我们要存储学生的成绩,那就要一个学生的姓名,学号,课程名字,课程成绩等等,假定一个学生要二十字节的空间,一个学院五千人,那就要10万字节。如果你硬要用数组存储,你得找到一块连续的10万字节的空间,很难吧。用链表就不需要,一块连续且这么大的空间。

三、链表相关知识

头结点:单链表的第一个结点,头结点的数据域不存储信息,指针域指向第一个有效结点即首结点。头结点的作用是使所有链表(包括空表)的头指针非空,其实头结点的作用是为了方便操作。

首结点:存放第一个有效数据的节点。

头指针:指向头节点的指针。

尾节点:存放最后一个有效数据的节点。

尾指针:指向尾节点的指针。

四、链表实现

1.定义结构体

  1. typedef struct Node
  2. {
  3. Elemtype data;//数据域
  4. struct Node* pNext;//指针域
  5. }NODE, * PNODE;//NODE相当于struct Node,* PNODE相当于struct Node *

结构体大同小异,主要分为数据域和指针域。看需求修改数据域,比如你存放学生成绩,那就多定义一些数据类型就好。

2.创建链表

  1. PNODE create_list()//创建链表
  2. {
  3. int length, value;
  4. PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配头结点
  5. if (NULL == pHead)
  6. {
  7. printf("分配内存失败,程序结束!\n");
  8. exit(-1);
  9. }
  10. PNODE pTail = pHead;//尾结点,每次增加结点时,尾结点跟着后移
  11. pTail->pNext = NULL;
  12. printf("链表结点个数:");
  13. scanf("%d", &length);
  14. for (int i = 0; i < length; i++)
  15. {
  16. printf("输入第%d个结点的值:", i + 1);
  17. scanf("%d", &value);
  18. PNODE pNew = (PNODE)malloc(sizeof(NODE));
  19. if (NULL == pNew)
  20. {
  21. printf("分配内存失败,程序结束\n");
  22. exit(-1);
  23. }
  24. pNew->data = value;
  25. pTail->pNext = pNew;
  26. pNew->pNext = NULL;
  27. pTail = pNew;
  28. }
  29. return pHead;
  30. }

使用尾指针方便操作,链表操作里面,经常要多定义一两个指针辅助功能实现。

3.遍历链表

  1. void traverse_list(PNODE pHead)//遍历链表
  2. {
  3. PNODE p = pHead->pNext;//用指针p指向第一个结点
  4. while (p != NULL)
  5. {
  6. printf("%-4d", p->data);
  7. p = p->pNext;
  8. }
  9. printf("\n");
  10. }

把头指针赋值给另外一个新的指针,遍历时就移动新指针就好了。

4.判断链表是否为空

  1. bool is_empty(PNODE pHead)//判断链表是否为空
  2. {
  3. if (NULL == pHead->pNext)
  4. return true;
  5. else
  6. return false;
  7. }

5.计算链表长度

  1. int length_list(PNODE pHead)//计算链表长度
  2. {
  3. PNODE p = pHead->pNext;
  4. int length = 0;
  5. while (p != NULL)
  6. {
  7. length++;
  8. p = p->pNext;
  9. }
  10. return length;
  11. }

6.插入一个数据

  1. bool insert_list(PNODE pHead, int position, int value)//在第position个结点前面插入一个结点
  2. {
  3. int i = 0;
  4. PNODE p = pHead;
  5. while (p != NULL && i < position - 1)
  6. {
  7. p = p->pNext;
  8. i++;
  9. }
  10. if (i > position - 1 || NULL == p)
  11. return false;
  12. PNODE pNew = (PNODE)malloc(sizeof(NODE));
  13. if (NULL == pNew)
  14. {
  15. printf("内存分配失败\n");
  16. exit(-1);
  17. }
  18. pNew->data = value;
  19. PNODE q = p->pNext;
  20. p->pNext = pNew;
  21. pNew->pNext = q;
  22. return true;
  23. }

7.删除数据

  1. bool delect_list(PNODE pHead, int position, int* value)//删除第position个结点
  2. {
  3. int i = 0;
  4. PNODE p = pHead;
  5. while (p->pNext != NULL && i < position - 1)
  6. {
  7. p = p->pNext;
  8. i++;
  9. }
  10. if (i > position - 1 || NULL == p->pNext)
  11. return false;
  12. PNODE q = p->pNext;
  13. *value = q->data;
  14. p->pNext = p->pNext->pNext;
  15. free(q);
  16. q = NULL;
  17. return true;
  18. }

删完记得释放内存,否则造成内存泄漏。

排序

  1. void sort_list(PNODE pHead)//排序
  2. {
  3. int length = length_list(pHead);
  4. int i, j, t;
  5. PNODE p, q;
  6. for (i = 0,p = pHead->pNext; i < length - 1; i++, p = p->pNext)
  7. {
  8. for (j = i + 1, q = p->pNext; j < length; j++, q = q->pNext)
  9. {
  10. if (p->data > q->data)
  11. {
  12. t = p->data;
  13. p->data = q->data;
  14. q->data = t;
  15. }
  16. }
  17. }
  18. }

8.全部代码

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdlib.h>
  4. #pragma warning(disable : 4996)
  5. typedef int Elemtype;
  6. typedef struct Node
  7. {
  8. Elemtype data;//数据域
  9. struct Node* pNext;//指针域
  10. }NODE, * PNODE;//NODE相当于struct Node,* PNODE相当于struct Node *
  11. PNODE create_list();
  12. void traverse_list(PNODE pHead);
  13. bool is_empty(PNODE pHead);
  14. int length_list(PNODE pHead);
  15. bool insert_list(PNODE pHead, int position, int value);
  16. bool delect_list(PNODE pHead, int position, int* value);
  17. void sort_list(PNODE pHead);
  18. int main()
  19. {
  20. PNODE pHead = NULL;
  21. int value;
  22. pHead = create_list();//创建非循环单链表
  23. traverse_list(pHead);
  24. if (is_empty(pHead))
  25. printf("链表为空\n");
  26. else
  27. printf("链表不为空\n");
  28. int length = length_list(pHead);
  29. printf("链表长度为%d\n", length);
  30. insert_list(pHead, 4, 75);
  31. traverse_list(pHead);
  32. sort_list(pHead);
  33. traverse_list(pHead);
  34. if (delect_list(pHead, 4, &value))
  35. {
  36. printf("删除成功,删除的元素为%d\n", value);
  37. }
  38. else
  39. {
  40. printf("删除失败,删除的元素不存在\n");
  41. }
  42. traverse_list(pHead);
  43. return 0;
  44. }
  45. PNODE create_list()//创建链表
  46. {
  47. int length, value;
  48. PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配头结点
  49. if (NULL == pHead)
  50. {
  51. printf("分配内存失败,程序结束!\n");
  52. exit(-1);
  53. }
  54. PNODE pTail = pHead;//尾结点,每次增加结点时,尾结点跟着后移
  55. pTail->pNext = NULL;
  56. printf("链表结点个数:");
  57. scanf("%d", &length);
  58. for (int i = 0; i < length; i++)
  59. {
  60. printf("输入第%d个结点的值:", i + 1);
  61. scanf("%d", &value);
  62. PNODE pNew = (PNODE)malloc(sizeof(NODE));
  63. if (NULL == pNew)
  64. {
  65. printf("分配内存失败,程序结束\n");
  66. exit(-1);
  67. }
  68. pNew->data = value;
  69. pTail->pNext = pNew;
  70. pNew->pNext = NULL;
  71. pTail = pNew;
  72. }
  73. return pHead;
  74. }
  75. void traverse_list(PNODE pHead)//遍历链表
  76. {
  77. PNODE p = pHead->pNext;//用指针p指向第一个结点
  78. while (p != NULL)
  79. {
  80. printf("%-4d", p->data);
  81. p = p->pNext;
  82. }
  83. printf("\n");
  84. }
  85. bool is_empty(PNODE pHead)//判断链表是否为空
  86. {
  87. if (NULL == pHead->pNext)
  88. return true;
  89. else
  90. return false;
  91. }
  92. int length_list(PNODE pHead)//计算链表长度
  93. {
  94. PNODE p = pHead->pNext;
  95. int length = 0;
  96. while (p != NULL)
  97. {
  98. length++;
  99. p = p->pNext;
  100. }
  101. return length;
  102. }
  103. bool insert_list(PNODE pHead, int position, int value)//在第position个结点前面插入一个结点
  104. {
  105. int i = 0;
  106. PNODE p = pHead;
  107. while (p != NULL && i < position - 1)
  108. {
  109. p = p->pNext;
  110. i++;
  111. }
  112. if (i > position - 1 || NULL == p)
  113. return false;
  114. PNODE pNew = (PNODE)malloc(sizeof(NODE));
  115. if (NULL == pNew)
  116. {
  117. printf("内存分配失败\n");
  118. exit(-1);
  119. }
  120. pNew->data = value;
  121. PNODE q = p->pNext;
  122. p->pNext = pNew;
  123. pNew->pNext = q;
  124. return true;
  125. }
  126. bool delect_list(PNODE pHead, int position, int* value)//删除第position个结点
  127. {
  128. int i = 0;
  129. PNODE p = pHead;
  130. while (p->pNext != NULL && i < position - 1)
  131. {
  132. p = p->pNext;
  133. i++;
  134. }
  135. if (i > position - 1 || NULL == p->pNext)
  136. return false;
  137. PNODE q = p->pNext;
  138. *value = q->data;
  139. p->pNext = p->pNext->pNext;
  140. free(q);
  141. q = NULL;
  142. return true;
  143. }
  144. void sort_list(PNODE pHead)//排序
  145. {
  146. int length = length_list(pHead);
  147. int i, j, t;
  148. PNODE p, q;
  149. for (i = 0,p = pHead->pNext; i < length - 1; i++, p = p->pNext)
  150. {
  151. for (j = i + 1, q = p->pNext; j < length; j++, q = q->pNext)
  152. {
  153. if (p->data > q->data)
  154. {
  155. t = p->data;
  156. p->data = q->data;
  157. q->data = t;
  158. }
  159. }
  160. }
  161. }

主函数内容仅仅是测试功能而已,最重要是理解各个函数是实现对应的功能。

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

闽ICP备14008679号