C语言实现单向循环链表,主要功能为空链表创建,链表初始化(头插法,尾插法),链表元素读取,按位置插入,(有序链表)按值插入,按位置删除,按值删除,清空链表,销毁链表。

  单向循环链表和单向链表的区别:(1)单向链表为头指针,循环链表为尾指针,头指针指向头结点,尾指针指向终端结点;(2)为统一方便操作,单向链表设置头结点,单向循环链表设置头结点和尾结点;(3)设置尾结点后,尾指针指向尾结点,插入,删除等操作不用移动尾指针。

  关键思路:创建头结点和尾结点。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct Node{
  5. int data;
  6. struct Node *next;
  7. }Node;
  8.  
  9. //空循环链表创建
  10. //创建头结点和尾结点
  11. //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
  12. void iniCList(Node **CListTail){
  13. *CListTail = (Node *)malloc(sizeof(Node));
  14. Node *CListHead = (Node *)malloc(sizeof(Node));
  15. if (NULL == *CListTail || NULL == CListHead){
  16. exit();
  17. }
  18.  
  19. (*CListTail)->next = CListHead;
  20. CListHead->next = *CListTail;
  21. }
  22.  
  23. //循环链表初始化(头插法)
  24. void iniCListHead(Node **CListTail, int n){
  25. //创建头尾结点
  26. *CListTail = (Node *)malloc(sizeof(Node));
  27. Node *CListHead = (Node *)malloc(sizeof(Node));
  28. if (NULL == *CListTail || NULL == CListHead){
  29. exit();
  30. }
  31.  
  32. (*CListTail)->next = CListHead;
  33. CListHead->next = *CListTail;
  34.  
  35. int i = ;
  36. while (i < n){
  37.  
  38. Node *tmpNode = (Node *)malloc(sizeof(Node));
  39. if (NULL == tmpNode){
  40. exit();
  41. }
  42. tmpNode->data = i;
  43. tmpNode->next = CListHead->next;
  44. CListHead->next = tmpNode;
  45. ++i;
  46. }
  47. }
  48.  
  49. //循环链表初始化(尾插法)
  50. void iniCListTail(Node **CListTail, int n){
  51. //创建头尾结点
  52. *CListTail = (Node *)malloc(sizeof(Node));
  53. Node *CListHead = (Node *)malloc(sizeof(Node));
  54. if (NULL == *CListTail || NULL == CListHead){
  55. exit();
  56. }
  57.  
  58. (*CListTail)->next = CListHead;
  59. CListHead->next = *CListTail;
  60.  
  61. Node *pCurrent = CListHead;
  62.  
  63. int i = ;
  64. while (i < n){
  65. Node *tmpNode = (Node *)malloc(sizeof(Node));
  66. if (NULL == tmpNode){
  67. exit();
  68. }
  69. tmpNode->data = i;
  70. tmpNode->next = *CListTail;
  71. pCurrent->next = tmpNode;
  72. pCurrent = tmpNode;
  73.  
  74. ++i;
  75. }
  76. }
  77.  
  78. //循环链表按位置插入
  79. void insertCListPos(Node *CList, int pos, int val){
  80.  
  81. Node *pCurrent = CList->next; //指向头结点
  82. int i = ;
  83. while (pCurrent != CList && i < pos){
  84. pCurrent = pCurrent->next;
  85. ++i;
  86. }
  87.  
  88. Node *tmpNode = (Node *)malloc(sizeof(Node));
  89. if (NULL == tmpNode){
  90. exit();
  91. }
  92. tmpNode->data = val;
  93. tmpNode->next = pCurrent->next;
  94. pCurrent->next = tmpNode;
  95.  
  96. }
  97.  
  98. //有序循环链表,按值插入
  99. void insertCListValue(Node *CList, int val){
  100. Node *pCur = CList->next->next;
  101. Node *pPer = CList->next;
  102.  
  103. while (pCur != CList && pCur->data < val){
  104. pPer = pCur;
  105. pCur = pCur->next;
  106. }
  107.  
  108. Node *tmpNode = (Node *)malloc(sizeof(Node));
  109. if (NULL == tmpNode){
  110. exit();
  111. }
  112. tmpNode->data = val;
  113. tmpNode->next = pPer->next;
  114. pPer->next = tmpNode;
  115. }
  116.  
  117. //循环链表,按位置删除
  118. void deleteCListPos(Node *CList, int pos){
  119. Node *pCur = CList->next;
  120.  
  121. int i = ;
  122. while (pCur != CList && i < pos){
  123. pCur = pCur->next;
  124. ++i;
  125. }
  126.  
  127. Node *tmpNode = pCur->next;
  128. pCur->next = tmpNode->next;
  129. free(tmpNode);
  130. }
  131.  
  132. //循环链表,按值删除
  133. //删除空链表为出问题
  134. void deleteCListValue(Node *CList, int val){
  135. Node *pCur = CList->next->next;
  136. Node *pPer = CList->next;
  137.  
  138. while (pCur != CList && pCur->data != val){
  139. pPer = pCur;
  140. pCur = pCur->next;
  141. }
  142. if (pCur == CList)
  143. return;
  144. else{
  145. pPer->next = pCur->next;
  146. free(pCur);
  147. }
  148. }
  149.  
  150. //循环链表,清空链表
  151. void claerCList(Node *CList){
  152. Node *p = CList->next->next;
  153. Node *q = NULL;
  154.  
  155. while (p != CList){ //到达表尾
  156. q = p->next;
  157. free(p);
  158. p = q;
  159. }
  160.  
  161. CList->next = CList; //将头结点指向尾结点
  162. }
  163.  
  164. //循环链表,销毁链表
  165. void destoryCList(Node **CList){
  166. Node *p = (*CList)->next;
  167. Node *q = NULL;
  168.  
  169. while (p != (*CList)->next){ //到达表头
  170. q = p->next;
  171. free(p);
  172. p = q;
  173. }
  174.  
  175. *CList = NULL;
  176. }
  177.  
  178. //获取元素
  179. void getCList(Node *CList, int pos, int *val){
  180. Node *pCur = CList->next->next;
  181. int i = ;
  182. while (pCur != CList && i < pos){
  183. pCur = pCur->next;
  184. ++i;
  185. }
  186.  
  187. *val = pCur->data;
  188. }
  189. //遍历输出元素
  190. void printCList(Node *CList){
  191. Node * tmpNode = CList->next->next;
  192. while (tmpNode != CList){ //到达表尾
  193. printf("%d\n", tmpNode->data);
  194. tmpNode = tmpNode->next;
  195. }
  196. }
  197.  
  198. int main(){
  199. Node *CList = NULL;
  200. //iniCListHead(&CList, 8);
  201. //iniCList(&CList);
  202. iniCListTail(&CList, );
  203.  
  204. //insertCListPos(CList, 1, 2);
  205. //insertCListPos(CList, 2, 4);
  206. //insertCListPos(CList, 3, 6);
  207. //
  208. //insertCListValue(CList, 1);
  209. //
  210. //deleteCListPos(CList, 3);
  211. //
  212. //deleteCListValue(CList, 6);
  213.  
  214. //claerCList(CList);
  215.  
  216. int a = ;
  217. getCList(CList, , &a);
  218. printf("%d\n", a);
  219.  
  220. printCList(CList);
  221.  
  222. printf("%d\n", CList);
  223. destoryCList(&CList);
  224. printf("%d\n", CList);
  225.  
  226. system("pause");
  227. return ;
  228. }

C语言完整代码

  通过C++实现C语言的链表,主要区别:(1)struct可以不通过typedef,直接使用Node;(2)将malloc和free更换为new和delete

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct Node{
  5. int data;
  6. struct Node *next;
  7. };
  8.  
  9. //空循环链表创建
  10. //创建头结点和尾结点
  11. //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
  12. void iniCList(Node **CListTail){
  13. *CListTail = new Node;
  14. Node *CListHead = new Node;
  15.  
  16. (*CListTail)->next = CListHead;
  17. CListHead->next = *CListTail;
  18. }
  19.  
  20. //循环链表初始化(头插法)
  21. void iniCListHead(Node **CListTail, int n){
  22. //创建头尾结点
  23. *CListTail = new Node;
  24. Node *CListHead = new Node;
  25.  
  26. (*CListTail)->next = CListHead;
  27. CListHead->next = *CListTail;
  28.  
  29. int i = ;
  30. while (i < n){
  31. Node *tmpNode = new Node;
  32.  
  33. tmpNode->data = i;
  34. tmpNode->next = CListHead->next;
  35. CListHead->next = tmpNode;
  36. ++i;
  37. }
  38. }
  39.  
  40. //循环链表初始化(尾插法)
  41. void iniCListTail(Node **CListTail, int n){
  42. //创建头尾结点
  43. *CListTail = new Node;
  44. Node *CListHead = new Node;
  45.  
  46. (*CListTail)->next = CListHead;
  47. CListHead->next = *CListTail;
  48.  
  49. Node *pCurrent = CListHead;
  50.  
  51. int i = ;
  52. while (i < n){
  53. Node *tmpNode = new Node;
  54.  
  55. tmpNode->data = i;
  56. tmpNode->next = *CListTail;
  57. pCurrent->next = tmpNode;
  58. pCurrent = tmpNode;
  59.  
  60. ++i;
  61. }
  62. }
  63.  
  64. //循环链表按位置插入
  65. void insertCListPos(Node *CList, int pos, int val){
  66.  
  67. Node *pCurrent = CList->next; //指向头结点
  68. int i = ;
  69. while (pCurrent != CList && i < pos){
  70. pCurrent = pCurrent->next;
  71. ++i;
  72. }
  73.  
  74. Node *tmpNode = new Node;
  75.  
  76. tmpNode->data = val;
  77. tmpNode->next = pCurrent->next;
  78. pCurrent->next = tmpNode;
  79.  
  80. }
  81.  
  82. //有序循环链表,按值插入
  83. void insertCListValue(Node *CList, int val){
  84. Node *pCur = CList->next->next;
  85. Node *pPer = CList->next;
  86.  
  87. while (pCur != CList && pCur->data < val){
  88. pPer = pCur;
  89. pCur = pCur->next;
  90. }
  91.  
  92. Node *tmpNode = new Node;
  93.  
  94. tmpNode->data = val;
  95. tmpNode->next = pPer->next;
  96. pPer->next = tmpNode;
  97. }
  98.  
  99. //循环链表,按位置删除
  100. void deleteCListPos(Node *CList, int pos){
  101. Node *pCur = CList->next;
  102.  
  103. int i = ;
  104. while (pCur != CList && i < pos){
  105. pCur = pCur->next;
  106. ++i;
  107. }
  108.  
  109. Node *tmpNode = pCur->next;
  110. pCur->next = tmpNode->next;
  111. delete tmpNode;
  112. }
  113.  
  114. //循环链表,按值删除
  115. //删除空链表为出问题
  116. void deleteCListValue(Node *CList, int val){
  117. Node *pCur = CList->next->next;
  118. Node *pPer = CList->next;
  119.  
  120. while (pCur != CList && pCur->data != val){
  121. pPer = pCur;
  122. pCur = pCur->next;
  123. }
  124. if (pCur == CList)
  125. return;
  126. else{
  127. pPer->next = pCur->next;
  128. delete pCur;
  129. }
  130. }
  131.  
  132. //循环链表,清空链表
  133. void claerCList(Node *CList){
  134. Node *p = CList->next->next;
  135. Node *q = NULL;
  136.  
  137. while (p != CList){ //到达表尾
  138. q = p->next;
  139. delete p;
  140. p = q;
  141. }
  142.  
  143. CList->next = CList; //将头结点指向尾结点
  144. }
  145.  
  146. //循环链表,销毁链表
  147. void destoryCList(Node **CList){
  148. Node *p = (*CList)->next;
  149. Node *q = NULL;
  150.  
  151. while (p != (*CList)->next){ //到达表头
  152. q = p->next;
  153. delete p;
  154. p = q;
  155. }
  156.  
  157. *CList = NULL;
  158. }
  159.  
  160. //获取元素
  161. void getCList(Node *CList, int pos, int *val){
  162. Node *pCur = CList->next->next;
  163. int i = ;
  164. while (pCur != CList && i < pos){
  165. pCur = pCur->next;
  166. ++i;
  167. }
  168.  
  169. *val = pCur->data;
  170. }
  171. //遍历输出元素
  172. void printCList(Node *CList){
  173. Node * tmpNode = CList->next->next;
  174. while (tmpNode != CList){ //到达表尾
  175. printf("%d\n", tmpNode->data);
  176. tmpNode = tmpNode->next;
  177. }
  178. }
  179.  
  180. int main(){
  181. Node *CList = NULL;
  182. //iniCListHead(&CList, 8);
  183. //iniCList(&CList);
  184. iniCListTail(&CList, );
  185.  
  186. //insertCListPos(CList, 1, 2);
  187. //insertCListPos(CList, 2, 4);
  188. //insertCListPos(CList, 3, 6);
  189. //
  190. //insertCListValue(CList, 1);
  191. //
  192. //deleteCListPos(CList, 3);
  193. //
  194. //deleteCListValue(CList, 6);
  195.  
  196. //claerCList(CList);
  197.  
  198. int a = ;
  199. getCList(CList, , &a);
  200. printf("%d\n", a);
  201.  
  202. printCList(CList);
  203.  
  204. printf("%d\n", CList);
  205. destoryCList(&CList);
  206. printf("%d\n", CList);
  207.  
  208. system("pause");
  209. return ;
  210. }

C++完整代码

单向循环链表

  注意:(1)单向循环链表销毁时,需要将头结点和尾结点删除;(2)单向循环链表插入,删除,遍历,清空链表时,条件从头结点或第一节点始,判断指针是否达到尾结点;(3)清空链表时,最后将头结点指向尾结点;(4)销毁链表时,条件从头结点始,判断条件为指针是否到达头结点,最后将指针置空。

-------------------------------------------------------------------------------------------------------------

如果上面的资料对你有启发,麻烦点个推荐,让更多人的人看到哦。

关注公众号【两猿社】,懂点互联网,懂点IC的程序猿,带你丰富项目经验哦。

C/C++实现单向循环链表(尾指针,带头尾节点)的更多相关文章

  1. python中的单向循环链表实现

    引子 所谓单向循环链表,不过是在单向链表的基础上,如响尾蛇般将其首尾相连,也因此有诸多类似之处与务必留心之点.尤其是可能涉及到头尾节点的操作,不可疏忽. 对于诸多操所必须的遍历,这时的条件是什么?又应 ...

  2. c语言实现--单向循环链表操作

    1,什么叫单向循环链表.单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空. 2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头. 3,链表的结点表示 1 ...

  3. ※数据结构※→☆线性表结构(list)☆============单向循环链表结构(list circular single)(四)

    循环链表是另一种形式的链式存贮结构.它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环. 单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可. 循环链表的 ...

  4. Python 单向循环链表

    操作 is_empty() 判断链表是否为空 length() 返回链表的长度 travel() 遍历 add(item) 在头部添加一个节点 append(item) 在尾部添加一个节点 inser ...

  5. 单向循环链表C语言实现

    我们都知道,单向链表最后指向为NULL,也就是为空,那单向循环链表就是不指向为NULL了,指向头节点,所以下面这个程序运行结果就是,你将会看到遍历链表的时候就是一个死循环,因为它不指向为NULL,也是 ...

  6. python实现单向循环链表

    单向循环链表 单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点. 实现 class Node(object): """节 ...

  7. JAVA单链表的实现-不带头结点且没有尾指针

    本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有 ...

  8. 复习下C 链表操作(单向循环链表、查找循环节点)

    循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表.  接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...

  9. (java实现)单向循环链表

    什么是单向循环链表 单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是null,而是头节点(注意:不是头指针). 因此,单向循环链表的任何节点的下一部分都不存在NULL值. ...

随机推荐

  1. 多flavor导致的源码依赖问题-- Cannot choose between the following configurations of project :sample:

    一.背景: 当我们在源码依赖的时候经常会导致一些问题. 我们的主工程有如下配置,它依赖了一个sample的本地工程 flavorDimensions "demo" productF ...

  2. Elastic Search 小调研

    一.概况: Elastic Search 是一个基于Apache Lucene™工具包的开源搜索引擎.无论在开源还是专有领域,Lucene 可以被认为是迄今为止最先进.性能最好的.功能最全的搜索引擎库 ...

  3. wget 下载文件

    # -c 继续执行上次终端的任务# --http-user http用户名# --http-passwd http密码# --no-check-certificate 不检查ssl/tsl证书. wg ...

  4. QueryList.class.php很方便的一个采集数据工具。

    QueryList.class.php是一个非常方面的网站数据采集工具.可以在这个上面采集别的网站数据. /*调用开始*/ require 'QueryList.class.php';header(' ...

  5. Delphi 中多线程同步的一些处理方法

    Delphi 中多线程同步的一些处理方法   当创建了多个线程,并且多个线程都要访问同一资源,,就有可能出现混乱,于是用Synchronize来控制,使同一时间只有一个线程使用那部分资源,Synchr ...

  6. 理解TCP/IP,SOCKET,HTTP,FTP,RMI,RPC,webservic

    TCP/IP:网络宽带,传输数据的基础协议,所有得数据要在网络上传输都是基于TCP/IP协议(或UDP),才能送达到指定的目的地(IP,服务器硬件地址). SOCKET:SOCKET只是面对编程人员的 ...

  7. java script 基本函数

    Math.random()    是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值. 日期时间函数(需要用变量调用):var b = new Date();      // ...

  8. 【Codeforces Round #589 (Div. 2) D】Complete Tripartite

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 其实这道题感觉有点狗. 思路大概是这样 先让所有的点都在1集合中. 然后随便选一个点x,访问它的出度y 显然tag[y]=2 因为和他相连了嘛 ...

  9. Qt5编译使用QFtp

    使用 QNetworkAccessManager 可以实现 Ftp 的上传/下载功能(参考:Qt之FTP上传/下载),但有些原本 QFtp 有的功能 QNetworkAccessManager 却没有 ...

  10. [转]关于tomcat 中的 tomcat-users.xml 配置不生效原因

    安装完tomcat,或者解压完tomcat后,在tomcat的目录下有个conf文件夹,在这个文件夹下面有一个tomcat- users.xml的文件,这个文件里面的配置信息是当我们进入http:// ...