单向顺序链表的创建,增,删,减,查

打印 上一主题 下一主题

主题 880|帖子 880|积分 2640

单向顺序链表的创建,增,删,减,查
  1. /*******************************************************************
  2. *
  3. *        file name:        单向顺序链表的创建,增,删,减,查
  4. *        author         :  17647576169@163.com
  5. *        date         :        2024-4-22
  6. *        function :
  7. *         note         :  None
  8. *
  9. *        CopyRight (c)  2024   17647576169@163.com   All Right Reseverd
  10. *
  11. * *****************************************************************/
  12. #include <stdbool.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. // 指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
  17. typedef int DataType_t;
  18. // 构造链表的结点,链表中所有结点的数据类型应该是相同的
  19. typedef struct LinkedList
  20. {
  21.         DataType_t data;                 // 结点的数据域
  22.         struct LinkedList *next; // 结点的指针域
  23. } LList_t;
  24. /********************************************************************
  25. *
  26. *        name         :        LList_Create
  27. *        function :  创建一个空的单向顺序链表,空链表应该有一个头结点,对链表进行初始化
  28. *        argument :        None
  29. *
  30. *        retval         :  返回创建的链表的头地址
  31. *        author         :  17647576169@163.com
  32. *        date         :  2024-4-22
  33. *         note         :
  34. *
  35. * *****************************************************************/
  36. LList_t *LList_Create(void)
  37. {
  38.         // 1.创建一个头结点并对头结点申请内存
  39.         LList_t *Head = (LList_t *)calloc(1, sizeof(LList_t));
  40.         if (NULL == Head)
  41.         {
  42.                 perror("Calloc memory for Head is Failed");
  43.                 exit(-1);
  44.         }
  45.         // 2.对头结点进行初始化,头结点是不存储有效内容的!!!
  46.         Head->next = NULL;
  47.         // 3.把头结点的地址返回即可
  48.         return Head;
  49. }
  50. /********************************************************************
  51. *
  52. *        name         :        LList_NewNode
  53. *        function :  创建新的结点,并对新结点进行初始化(数据域 + 指针域)
  54. *        argument :        @data:需插入的数据
  55. *
  56. *        retval         :  返回新创建链表节点的地址
  57. *        author         :  17647576169@163.com
  58. *        date         :  2024-4-22
  59. *         note         :
  60. *
  61. * *****************************************************************/
  62. LList_t *LList_NewNode(DataType_t data)
  63. {
  64.         // 1.创建一个新结点并对新结点申请内存
  65.         LList_t *New = (LList_t *)calloc(1, sizeof(LList_t));
  66.         if (NULL == New)
  67.         {
  68.                 perror("Calloc memory for NewNode is Failed");
  69.                 return NULL;
  70.         }
  71.         // 2.对新结点的数据域和指针域进行初始化
  72.         New->data = data;
  73.         New->next = NULL;
  74.         return New;
  75. }
  76. /********************************************************************
  77. *
  78. *        name         :        LList_HeadInsert
  79. *        function :  向链表的头部进行数据插入
  80. *        argument :        @head:目标链表
  81. *                                @data:需插入的数据
  82. *        retval         :  返回新创建链表节点的地址
  83. *        author         :  17647576169@163.com
  84. *        date         :  2024-4-22
  85. *         note         :
  86. *
  87. * *****************************************************************/
  88. bool LList_HeadInsert(LList_t *Head, DataType_t data)
  89. {
  90.         // 1.创建新的结点,并对新结点进行初始化
  91.         LList_t *New = LList_NewNode(data);
  92.         if (NULL == New)
  93.         {
  94.                 printf("can not insert new node\n");
  95.                 return false;
  96.         }
  97.         // 2.判断链表是否为空,如果为空,则直接插入即可
  98.         if (NULL == Head->next)
  99.         {
  100.                 Head->next = New;
  101.                 return true;
  102.         }
  103.         // 3.如果链表为非空,则把新结点插入到链表的头部
  104.         New->next = Head->next;
  105.         Head->next = New;
  106.         return true;
  107. }
  108. /********************************************************************
  109. *
  110. *        name         :        LList_TailInsert
  111. *        function :  向链表的尾部进行数据插入
  112. *        argument :        @head:目标链表
  113. *                                @data:需插入的数据
  114. *        retval         :  返回1成功0失败
  115. *        author         :  17647576169@163.com
  116. *        date         :  2024-4-22
  117. *         note         :
  118. *
  119. * *****************************************************************/
  120. bool LList_TailInsert(LList_t *Head, DataType_t data)
  121. {
  122.         // 1.创建新的结点,并对新结点进行初始化
  123.         LList_t *New = LList_NewNode(data);
  124.         if (NULL == New)
  125.         {
  126.                 printf("can not insert new node\n");
  127.                 return false;
  128.         }
  129.         // 2.判断链表是否为空,如果为空,则直接插入即可
  130.         if (NULL == Head->next)
  131.         {
  132.                 Head->next = New;
  133.                 return true;
  134.         }
  135.         // 3对链表的头文件的地址进行备份
  136.         LList_t *Phead = Head;
  137.         // 4遍历链表找到尾部
  138.         while (Phead->next)
  139.         {
  140.                 // 把头的直接后继作为新的头结点
  141.                 Phead = Phead->next;
  142.         }
  143.         // 5.把新结点插入到链表的尾部
  144.         Phead->next = New;
  145.         return true;
  146. }
  147. /********************************************************************
  148. *
  149. *        name         :        LList_TailInsert
  150. *        function :  向链表的任意位置插入
  151. *        argument :        @head:目标链表
  152. *                                @data:需插入的数据
  153. *                                @dest:插入位置
  154. *        retval         :  返回1成功0失败
  155. *        author         :  17647576169@163.com
  156. *        date         :  2024-4-22
  157. *         note         :
  158. *
  159. * *****************************************************************/
  160. bool LList_TailInsert(LList_t *Head, DataType_t data, int dest)
  161. {
  162.         // 1.创建新的结点,并对新结点进行初始化
  163.         LList_t *New = LList_NewNode(data);
  164.         if (NULL == New)
  165.         {
  166.                 printf("can not insert new node\n");
  167.                 return false;
  168.         }
  169.         // 2.判断链表是否为空,如果为空,则直接插入即可
  170.         if (NULL == Head->next)
  171.         {
  172.                 Head->next = New;
  173.                 return true;
  174.         }
  175.         if (NULL == Head->next->next)
  176.         {
  177.                 Head->next->next = New;
  178.                 return true;
  179.         }
  180.         // 定义两指针备份首节点地址及其后置
  181.         LList_t *P1 = Head->next;
  182.         LList_t *P2 = P1->next;
  183.         // 偏移找的插入位置
  184.         for (int i = 0; i < dest - 1; i++)
  185.         {
  186.                 P1 = P1->next;
  187.                 P2 = P2->next;
  188.         }
  189.         // 把新结点插入
  190.         New->next = P2->next;
  191.         P1->next = New;
  192.         P2->next = NULL;
  193.         free(P2);
  194.         return true;
  195. }
  196. /********************************************************************
  197. *
  198. *        name         :        LList_DestInsert
  199. *        function :  删除链表中的数据
  200. *        argument :        @head:目标链表
  201. *                                @data:需删除的数据
  202. *
  203. *        retval         :  返回1成功0失败
  204. *        author         :  17647576169@163.com
  205. *        date         :  2024-4-22
  206. *         note         :
  207. *
  208. * *****************************************************************/
  209. bool LList_DestInsert(LList_t *Head, DataType_t data)
  210. {
  211.         // 判断链表是否为空
  212.         if (NULL == Head->next)
  213.         {
  214.                 return false;
  215.         }
  216.         // 要删除的节点在第一个
  217.         if (data == Head->next)
  218.         {
  219.                 // 备份首节点地址
  220.                 LList_t *P = Head;
  221.                 Head->next = Head->next->next;
  222.                 P->next = NULL;
  223.                 free(P);
  224.                 return true;
  225.         }
  226.         {
  227.                 /* code */
  228.         }
  229.         // 备份头节点
  230.         LList_t *P1 = Head->next;
  231.         LList_t *P2 = P1->next;
  232.         while (P2->next)
  233.         {
  234.                 // 找到data数据所在位置
  235.                 if (data == P2->data)
  236.                 {
  237.                         // 如果data所在节点是为尾节点,如果在则执行删除
  238.                         if (NULL == P2->next)
  239.                         {
  240.                                 P1->next = NULL;
  241.                                 free(P2);
  242.                                 return true;
  243.                         }
  244.                         // 如果data所在节点不是为尾节点
  245.                         // P1链接P2的下节点
  246.                         P1 = P2->next;
  247.                         // 初始化P2的指针域
  248.                         P2->next = NULL;
  249.                         // 释放堆空间
  250.                         free(P2);
  251.                         return true;
  252.                 }
  253.                 // 偏移
  254.                 P1 = P1->next;
  255.                 P2 = P2->next;
  256.         }
  257. }
  258. /********************************************************************
  259. *
  260. *        name         :        LList_Print
  261. *        function :  遍历链表
  262. *        argument :        @head:目标链表
  263. *
  264. *
  265. *        retval         :  none
  266. *        author         :  17647576169@163.com
  267. *        date         :  2024-4-22
  268. *         note         :
  269. *
  270. * *****************************************************************/
  271. void LList_Print(LList_t *Head)
  272. {
  273.         // 对链表的头文件的地址进行备份
  274.         LList_t *Phead = Head;
  275.         // 首结点
  276.         while (Phead->next)
  277.         {
  278.                 // 把头的直接后继作为新的头结点
  279.                 Phead = Phead->next;
  280.                 // 输出头结点的直接后继的数据域
  281.                 printf("data = %d\n", Phead->data);
  282.         }
  283. }
  284. ​```
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表