ToB企服应用市场:ToB评测及商务社交产业平台

标题: C语言单向循环链表的增删操作 [打印本页]

作者: 种地    时间: 2024-5-18 05:03
标题: C语言单向循环链表的增删操作
  1. /********************************************************************************************************
  2. *
  3. *
  4. * 设计单向循环链表的接口
  5. *
  6. *
  7. *
  8. * Copyright (c)  2023-2024   a1583839363@163.com   All right Reserved
  9. * ******************************************************************************************************/
  10. //指的是单向循环链表中的结点有效数据类型,用户可以根据需要进行修改
  11. typedef int  DataType_t;
  12. //构造单向循环链表的结点,链表中所有结点的数据类型应该是相同的
  13. typedef struct CircularLinkedList
  14. {
  15.         DataType_t                   data; //结点的数据域
  16.         struct LinkedList        *next; //结点的指针域
  17. }CircLList_t;
  18. //创建一个空单向循环链表,空链表应该有一个头结点,对链表进行初始化
  19. CircLList_t * CircLList_Create(void)
  20. {
  21.         //1.创建一个头结点并对头结点申请内存
  22.         CircLList_t *Head = (CircLList_t *)calloc(1,sizeof(CircLList_t));
  23.         if (NULL == Head)
  24.         {
  25.                 perror("Calloc memory for Head is Failed");
  26.                 exit(-1);
  27.         }
  28.         //2.对头结点进行初始化,头结点是不存储数据域,指针域指向自身,体现“循环”思想
  29.         Head->next = Head;
  30.         //3.把头结点的地址返回即可
  31.         return Head;
  32. }
  33. //创建新的结点,并对新结点进行初始化(数据域 + 指针域)
  34. CircLList_t * CircLList_NewNode(DataType_t data)
  35. {
  36.         //1.创建一个新结点并对新结点申请内存
  37.         CircLList_t *New = (CircLList_t *)calloc(1,sizeof(CircLList_t));
  38.         if (NULL == New)
  39.         {
  40.                 perror("Calloc memory for NewNode is Failed");
  41.                 return NULL;
  42.         }
  43.         //2.对新结点的数据域和指针域进行初始化
  44.         New->data = data;
  45.         New->next = NULL;
  46.         return New;
  47. }
  48. //头插
  49. bool CircLList_HeadInsert(CircLList_t *Head,DataType_t data)
  50. {
  51.         // 1.创建新的结点,并对新结点进行初始化
  52.         CircLList_t *New = CircLList_NewNode(data);
  53.         if (NULL == New)
  54.         {
  55.                 printf("can not insert new node\n");
  56.                 return false;
  57.         }
  58.         // 2.判断单向循环链表是否为空,如果为空,则直接插入即可
  59.         if (NULL == Head->next)
  60.         {
  61.                 Head->next = New;
  62.         New->next = New;
  63.                 return true;
  64.         }
  65.     // 3.如果单向循环链表为非空,遍历找到尾结点
  66.     CircLList_t *Last = Head;
  67.     while(Last->next != Head->next)
  68.     {
  69.         Last = Last->next;
  70.     }
  71.         // 4.把新结点插入到链表的头部
  72.     New->next = Head->next;
  73.     Head->next = New;
  74.     Last->next = New;
  75.     return true;
  76. }
  77. //尾插
  78. bool CircLList_TailInsert(CircLList_t *Head,DataType_t data)
  79. {
  80.         // 1.创建新的结点,并对新结点进行初始化
  81.         CircLList_t *New = CircLList_NewNode(data);
  82.         if (NULL == New)
  83.         {
  84.                 printf("can not insert new node\n");
  85.                 return false;
  86.         }
  87.         // 2.判断单向循环链表是否为空,如果为空,则直接插入即可
  88.         if (NULL == Head->next)
  89.         {
  90.                 Head->next = New;
  91.         New->next = New;
  92.                 return true;
  93.         }
  94.     // 3.如果单向循环链表为非空,遍历找到尾结点
  95.     CircLList_t *Last = Head;
  96.     while(Last->next != Head->next)
  97.     {
  98.         Last = Last->next;
  99.     }
  100.     // 4.把新结点插入到链表的尾部
  101.     Last->next = New;
  102.     New->next = Head->next;
  103.     return true;
  104. }
  105. //指定位置插入
  106. bool CircLList_DestInsert(CircLList_t *Head,DataType_t destval,DataType_t data)
  107. {
  108.         // 1.创建新的结点,并对新结点进行初始化
  109.         CircLList_t *New = CircLList_NewNode(data);
  110.         if (NULL == New)
  111.         {
  112.                 printf("can not insert new node\n");
  113.                 return false;
  114.         }
  115.         // 2.判断单向循环链表是否为空,如果为空,则直接插入即可
  116.         if (NULL == Head->next)
  117.         {
  118.                 Head->next = New;
  119.         New->next = New;
  120.                 return true;
  121.         }
  122.     // 3.遍历链表,比较结点的数据域,找到目标结点
  123.         CircLList_t *Dest = Head->next;
  124.         while (Dest->data != destval && Dest != NULL)
  125.         {
  126.                 Dest = Dest->next;
  127.         }
  128.         if (NULL == Dest)
  129.         {
  130.                 return false;
  131.         }
  132.         // 4.说明找到目标结点,则把新结点插入到目标结点的后面
  133.         New->next = Dest->next;
  134.         Dest->next = New;
  135.     return true;
  136. }
  137. // 头删
  138. bool CircLList_HeadDel(CircLList_t *Head)
  139. {
  140.         // 1.判断链表是否为空,如果为空,则直接退出
  141.         if (NULL == Head->next)
  142.         {
  143.                 return false;
  144.         }
  145.     // 2.对链表的首结点的地址进行备份
  146.         CircLList_t *Temp = Head->next;
  147.         // 3.链表是非空的,遍历链表,找到尾结点
  148.     CircLList_t *Last = Head;
  149.     while(Last->next != Head->next)
  150.     {
  151.         Last = Last->next;
  152.     }
  153.     // 4.删除首结点
  154.         Last->next = Temp->next;
  155.     Head->next = Temp->next;
  156.         Temp->next = NULL;
  157.         free(Temp);
  158.         return true;
  159. }
  160. // 尾删
  161. bool CircLList_TailDel(CircLList_t *Head)
  162. {
  163.     // 1.判断链表是否为空,如果为空,则直接退出
  164.         if (NULL == Head->next)
  165.         {
  166.                 return false;
  167.         }
  168.     // 2.链表是非空的,遍历链表,找到尾结点以及尾结点的直接前驱
  169.     CircLList_t *Last_pre = Head;
  170.     CircLList_t *Last = Head->next;
  171.     while(Last->next != Head->next)
  172.     {
  173.         Last = Last->next;
  174.         Last_pre = Last_pre->next;
  175.     }
  176.     // 3.删除尾结点
  177.     Last_pre->next = Head->next;
  178.     Last->next = NULL;
  179.     free(Last);
  180.         return true;
  181. }
  182. // 指定删
  183. bool CircLList_DestDel(CircLList_t *Head, DataType_t destval, DataType_t data)
  184. {
  185.     // 1.判断链表是否为空,如果为空,则直接退出
  186.         if (NULL == Head->next)
  187.         {
  188.                 return false;
  189.         }
  190.     // 2.链表是非空的,遍历链表,找到待删除结点以及待删除结点的直接前驱
  191.         CircLList_t *Dest_pre = Head;
  192.     CircLList_t *Dest = Head->next;
  193.     while (Dest->data != destval && Dest != NULL)
  194.         {
  195.                 Dest = Dest->next;
  196.         Dest_pre = Dest_pre->next;
  197.         }
  198.         if (NULL == Dest)
  199.         {
  200.                 return false;
  201.         }
  202.     // 3.删除指定结点
  203.         Dest_pre->next = Dest->next;
  204.     Dest->next = NULL;
  205.         free(Dest);
  206.         return true;
  207. }
  208. //遍历链表
  209. bool CircLList_Print(CircLList_t *Head)
  210. {
  211.         //对单向循环链表的头结点的地址进行备份
  212.         CircLList_t *Phead = Head;
  213.        
  214.         //判断当前链表是否为空,为空则直接退出
  215.         if (Head->next == Head)
  216.         {
  217.                 printf("current linkeflist is empty!\n");
  218.                 return false;
  219.         }
  220.         //从首结点开始遍历
  221.         while(Phead->next)
  222.         {
  223.                 //把头结点的直接后继作为新的头结点
  224.                 Phead = Phead->next;
  225.                 //输出头结点的直接后继的数据域
  226.                 printf("data = %d\n",Phead->data);
  227.                 //判断是否到达尾结点,尾结点的next指针是指向首结点的地址
  228.                 if (Phead->next == Head->next)
  229.                 {
  230.                         break;
  231.                 }       
  232.         }
  233.         return true;
  234. }
  235. int main(int argc, char const *argv[])
  236. {
  237.        
  238.         return 0;
  239. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4