翼度科技»论坛 云主机 LINUX 查看内容

数据结构的练习day2(未完待续)

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
数据结构线性结构之单向循环链表的基本操作
  1. /********************************************************************************************************
  2. *
  3. *
  4. * 设计单向循环链表的接口
  5. *
  6. *
  7. *
  8. * Copyright (c)  2023-2024   17820413718@163.com   All right Reserved
  9. * ******************************************************************************************************/
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <stdbool.h>
  13. // 指的是单向循环链表中的结点有效数据类型,用户可以根据需要进行修改
  14. typedef int DataType_t;
  15. // 构造单向循环链表的结点,链表中所有结点的数据类型应该是相同的
  16. typedef struct CircularLinkedList
  17. {
  18.         DataType_t data;                                                                 // 结点的数据域
  19.         struct CircularLinkedList *next; // 结点的指针域
  20. } CircLList_t;
  21. // 遍历链表
  22. bool CircLList_Print(CircLList_t *Head)
  23. {
  24.         // 对单向循环链表的头结点的地址进行备份
  25.         CircLList_t *Phead = Head;
  26.         // 判断当前链表是否为空,为空则直接退出
  27.         if (Head->next == Head)
  28.         {
  29.                 printf("current linkeflist is empty!\n");
  30.                 return false;
  31.         }
  32.         // 从首结点开始遍历
  33.         while (Phead->next)
  34.         {
  35.                 // 把头结点的直接后继作为新的头结点
  36.                 Phead = Phead->next;
  37.                 // 输出头结点的直接后继的数据域
  38.                 printf("data = %d\n", Phead->data);
  39.                 // 判断是否到达尾结点,尾结点的next指针是指向首结点的地址
  40.                 if (Phead->next == Head->next)
  41.                 {
  42.                         break;
  43.                 }
  44.         }
  45.         return true;
  46. }
  47. // 创建一个空单向循环链表,空链表应该有一个头结点,对链表进行初始化
  48. CircLList_t *CircLList_Create(void)
  49. {
  50.         // 1.创建一个头结点并对头结点申请内存
  51.         CircLList_t *Head = (CircLList_t *)calloc(1, sizeof(CircLList_t));
  52.         if (NULL == Head)
  53.         {
  54.                 perror("Calloc memory for Head is Failed");
  55.                 exit(-1);
  56.         }
  57.         // 2.对头结点进行初始化,头结点是不存储数据域,指针域指向自身,体现“循环”思想
  58.         Head->next = Head;
  59.         // 3.把头结点的地址返回即可
  60.         return Head;
  61. }
  62. // 创建新的结点,并对新结点进行初始化(数据域 + 指针域)
  63. CircLList_t *CircLList_NewNode(DataType_t data)
  64. {
  65.         // 1.创建一个新结点并对新结点申请内存
  66.         CircLList_t *New = (CircLList_t *)calloc(1, sizeof(CircLList_t));
  67.         if (NULL == New)
  68.         {
  69.                 perror("Calloc memory for NewNode is Failed");
  70.                 return NULL;
  71.         }
  72.         // 2.对新结点的数据域和指针域进行初始化
  73.         New->data = data;
  74.         New->next = NULL;
  75.         return New;
  76. }
  77. // 头插
  78. bool CircLList_HeadInsert(CircLList_t *Head, DataType_t data)
  79. {
  80.         if (Head == NULL)
  81.         {
  82.                 printf("链表为空!\n");
  83.                 return false;
  84.         }
  85.         // 创建一个指针代替Head
  86.         CircLList_t *phead = Head;
  87.         // 新建一个结点
  88.         CircLList_t *newNode = CircLList_NewNode(data);
  89.         // 让新建的结点指向原来的首结点
  90.         newNode->next = phead->next;
  91.         // 让头结点指向新建的结点
  92.         phead->next = newNode;
  93.         return true;
  94. }
  95. // 尾插
  96. bool CircLList_TailInsert(CircLList_t *Head, DataType_t data)
  97. {
  98.         if (Head == NULL)
  99.         {
  100.                 printf("链表为空!\n");
  101.                 return false;
  102.         }
  103.         // 创建一个指针代替Head
  104.         CircLList_t *phead = Head->next;
  105.         // 新建一个结点
  106.         CircLList_t *newNode = CircLList_NewNode(data);
  107.         while (phead->next != Head)
  108.         {
  109.                 phead = phead->next;
  110.                 if (phead->next == Head->next)
  111.                 {
  112.                         break;
  113.                 }
  114.         }
  115.         //  尾结点指向新结点
  116.         phead->next = newNode;
  117.         // 新结点指向首结点
  118.         newNode->next = Head->next;
  119.         return true;
  120. }
  121. // 指定位置插入(后插)
  122. bool CircLList_DestInsert(CircLList_t *Head, DataType_t destval, DataType_t data)
  123. {
  124.         if (Head == NULL)
  125.         {
  126.                 printf("链表为空!\n");
  127.                 return false;
  128.         }
  129.         // 创建一个指针代替Head
  130.         CircLList_t *phead = Head;
  131.         // 新建一个结点
  132.         CircLList_t *newNode = CircLList_NewNode(data);
  133.         while (phead)
  134.         {
  135.                 // 找到目标结点的上前结点
  136.                 if (phead->next->data == destval)
  137.                 {
  138.                         break;
  139.                 }
  140.                 phead = phead->next;
  141.         }
  142.         newNode->next = phead->next;
  143.         phead->next = newNode;
  144. }
  145. // 头删
  146. bool CircLList_HeadDel(CircLList_t *Head)
  147. {
  148.         // 对单向循环链表的首结点的地址进行备份
  149.         CircLList_t *Phead = Head->next;
  150.         while (Phead->next != Head)
  151.         {
  152.                 if (Phead->next == Head->next)
  153.                 {
  154.                         break;
  155.                 }
  156.                 Phead = Phead->next;
  157.         }
  158.         Phead->next = Head->next->next;
  159.         Phead = Head->next;
  160.         Head->next = Head->next->next;
  161.         Phead->next = NULL;
  162.         free(Phead);
  163.         return true;
  164. }
  165. // 尾删
  166. bool CircLList_TailDel(CircLList_t *Head)
  167. {
  168.         // 对单向循环链表的首结点的地址进行备份
  169.         CircLList_t *phead = Head->next;
  170.         // 找到尾结点的前一个结点
  171.         while (phead->next->next != Head)
  172.         {
  173.                 if (phead->next->next == Head->next)
  174.                 {
  175.                         break;
  176.                 }
  177.                 phead = phead->next;
  178.         }
  179.         phead->next->next = NULL;
  180.         free(phead->next);
  181.         phead->next = Head->next;
  182.         return true;
  183. }
  184. // 指定数据的结点删除(后删)
  185. bool CircLList_DestDes(CircLList_t *Head, DataType_t destval)
  186. {
  187.         // 对单向循环链表的首结点的地址进行备份
  188.         CircLList_t *phead = Head->next;
  189.         // 前结点
  190.         CircLList_t *preNode = Head;
  191.         // 要删除的结点
  192.         CircLList_t *delNode = Head->next;
  193.         while (phead->next != Head)
  194.         {
  195.                 if (delNode->data == destval)
  196.                 {
  197.                         break;
  198.                 }
  199.                 preNode = delNode;
  200.                 delNode = delNode->next;
  201.         }
  202.         preNode->next = delNode->next;
  203.         delNode->next = NULL;
  204.         free(delNode);
  205.         return true;
  206. }
  207. int main(int argc, char const *argv[])
  208. {
  209.         CircLList_t *Head = CircLList_Create();
  210.         CircLList_HeadInsert(Head, 40);
  211.         CircLList_HeadInsert(Head, 30);
  212.         CircLList_HeadInsert(Head, 20);
  213.         CircLList_HeadInsert(Head, 10);
  214.         CircLList_TailInsert(Head, 50);
  215.         CircLList_DestInsert(Head, 30, 15);
  216.         CircLList_HeadDel(Head);
  217.         CircLList_Print(Head);
  218.         CircLList_TailDel(Head);
  219.         CircLList_DestDes(Head, 20);
  220.         CircLList_Print(Head);
  221.         return 0;
  222. }
复制代码
来源:https://www.cnblogs.com/DengJian111222/p/18153810
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具