循环链表是还有一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

循环链表的操作
1,循环链表的新操作
2, 获取当前游标指向的数据元素
3, 将游标重置指向链表中的第一个数据元素

4,将游标移动指向到链表中的下一个数据元素

5,直接指定删除链表中的某个数据元素

CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);
CircleListNode* CircleList_Reset(CircleList* list);
CircleListNode* CircleList_Current(CircleList* list);
CircleListNode* CircleList_Next(CircleList* list);

头文件:

  1. #ifndef _CIRCLE_H_
  2. #define _CIRCLE_H_
  3. //採用数据封装的方式。防止在主函数改动当中的属性值(有点点像面向对象中的私有属性)
  4. typedef void CircleList;
  5. typedef struct CircleListNode //声明指针域
  6. {
  7. CircleListNode * next;
  8. }CircleListNode;
  9. CircleList * CircleList_Create();
  10. void CircleList_DesTroy(CircleList * list);
  11. void CircleList_Clear(CircleList* list);
  12. int CircleList_Length(CircleList* list);
  13. int CircleList_Insert(CircleList* list, CircleListNode* node, int pos);
  14. CircleListNode* CircleList_Get(CircleList* list, int pos);
  15. CircleListNode* CircleList_Delete(CircleList* list, int pos);
  16. CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node);
  17. CircleListNode* CircleList_Reset(CircleList* list);
  18. CircleListNode* CircleList_Current(CircleList* list);
  19. CircleListNode* CircleList_Next(CircleList* list) ;
  20. #endif

源文件:

  1. // 循环链表.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <malloc.h>
  5. #include <stdlib.h>
  6. #include "CircleList.h"
  7. typedef struct //定义头结点
  8. {
  9. CircleListNode header;
  10. CircleListNode* sLider; //游标
  11. int len;
  12. }TCircleList;
  13. struct Value //定义数据结构体类型
  14. {
  15. CircleListNode header; //指针域
  16. int v; //数据域
  17. };
  18. int _tmain(int argc, _TCHAR* argv[])
  19. {
  20. int i = 0;
  21. CircleList* list = CircleList_Create();
  22. struct Value v1;
  23. struct Value v2;
  24. struct Value v3;
  25. struct Value v4;
  26. struct Value v5;
  27. struct Value v6;
  28. struct Value v7;
  29. struct Value v8;
  30. v1.v = 1;
  31. v2.v = 2;
  32. v3.v = 3;
  33. v4.v = 4;
  34. v5.v = 5;
  35. v6.v = 6;
  36. v7.v = 7;
  37. v8.v = 8;
  38. CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));
  39. CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));
  40. CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));
  41. CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));
  42. //插入到 5 的位置,前面的顺序为 1->2->3->4
  43. // 下标: 0 1 2 3
  44. // 4 5 ...
  45. //故而插入到 5 的位置时 打印的结果应为 : 1,5,2,3,4。后面的结果也验证了其正确性
  46. CircleList_Insert(list, (CircleListNode*)&v5, 5);
  47. for(i=0; i<CircleList_Length(list); i++)
  48. {
  49. struct Value* pv = (struct Value*)CircleList_Get(list, i);
  50. printf("%d\n", pv->v);
  51. }
  52. while( CircleList_Length(list) > 0 )
  53. {
  54. struct Value* pv = (struct Value*)CircleList_Delete(list, 0);
  55. printf("删除了:%d\n", pv->v);
  56. }
  57. CircleList_DesTroy(list);
  58. system("pause");
  59. return 0;
  60. }
  61. //创建
  62. CircleList * CircleList_Create()
  63. {
  64. TCircleList* list = (TCircleList*)malloc(sizeof(TCircleList));
  65. if(NULL != list)
  66. {
  67. list->sLider = NULL;
  68. list->header.next = NULL;
  69. list->len = 0;
  70. }
  71. return list;
  72. }
  73. //销毁
  74. void CircleList_DesTroy(CircleList * list)
  75. {
  76. free(list);
  77. }
  78. //清空
  79. void CircleList_Clear(CircleList* list)
  80. {
  81. TCircleList * sList = (TCircleList*)list;
  82. if(NULL != sList)
  83. {
  84. sList->len = 0;
  85. sList->header.next = NULL;
  86. sList->sLider = NULL;
  87. }
  88. }
  89. //获得长度
  90. int CircleList_Length(CircleList* list)
  91. {
  92. TCircleList * sList = (TCircleList*)list;
  93. int len = -1;
  94. if(NULL != sList)
  95. {
  96. len = sList->len;
  97. }
  98. return len;
  99. }
  100. //插入  
  101. int CircleList_Insert(CircleList* list, CircleListNode* node, int pos)  
  102. {  
  103. TCircleList * sList = (TCircleList*)list;  
  104. int i = 0;  
  105. int ret = 0;  
  106. sList->len;  
  107. if((NULL != sList) && (pos>=0) && (NULL != node))  
  108. {  
  109.     CircleListNode * current = (CircleListNode*)sList;  
  110.     for ( i=0; i<pos && current->next != NULL; i++)  
  111.     {  
  112.     current = current->next;  
  113.     }  
  114.       
  115.     node->next = current->next;         
  116.     current->next = node;  
  117.     if(sList->len == 0)  
  118.     {  
  119.     sList->sLider = node;  
  120.       
  121.     }  
  122.     ++(sList->len);  
  123.     if( current == (CircleListNode*)sList )  
  124.     {  
  125.     CircleListNode* last = CircleList_Get(sList, sList->len - 1);              
  126.     last->next = current->next;  
  127.     }  
  128.     ret = 1;  
  129.       
  130.       
  131. }  
  132. return ret;  
  133. } 
  134. //获得结点
  135. CircleListNode* CircleList_Get(CircleList* list, int pos)
  136. {
  137. TCircleList * sList = (TCircleList*)list;
  138. CircleListNode * resNode = NULL;
  139. int i = 0;
  140. if((NULL != sList) && (pos>=0))
  141. {
  142. CircleListNode * current = (CircleListNode*)sList;
  143. for( i=0; i<pos; i++)
  144. {
  145. //i=0时,current为头结点,current->next为真正的第一个结点
  146. current = current->next;
  147. }
  148. resNode = current->next;
  149. }
  150. return resNode;
  151. }
  152. //删除
  153. CircleListNode* CircleList_Delete(CircleList* list, int pos)
  154. {
  155. TCircleList * sList = (TCircleList*)list;
  156. int i = 0;
  157. CircleListNode * resnode = NULL;
  158. CircleListNode* first = sList->header.next;
  159. CircleListNode* last = (CircleListNode*)CircleList_Get(list,sList->len-1);
  160. if((NULL != sList) && (pos >= 0) && (pos < sList->len))
  161. {
  162. CircleListNode * current = (CircleListNode*)sList;
  163. for ( i=0; i<pos; i++)
  164. {
  165. //i=0时,current为头结点,current->next为真正的第一个结点
  166. current = current->next;
  167. }
  168. resnode = current->next;
  169. current->next = resnode->next;
  170. if(first == resnode)
  171. {
  172. sList->header.next = first->next;
  173. last->next = first->next;
  174. }
  175. if(sList->sLider == resnode)
  176. {
  177. sList->sLider = resnode->next;
  178. }
  179. if(sList->len == 0)
  180. {
  181. sList->header.next = NULL;
  182. sList->sLider = NULL;
  183. }
  184. }
  185. sList->len--;
  186. return resnode;
  187. }
  188. //依据结点来删除
  189. CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node)
  190. {
  191. TCircleList * sList = (TCircleList*)list;
  192. CircleListNode* resnode = NULL;
  193. int i = 0;
  194. if(NULL != sList)
  195. {
  196. CircleListNode* current = (CircleListNode*)sList;
  197. for ( i=0; i<sList->len; i++)
  198. {
  199. if(node == current->next)
  200. {
  201. resnode = current->next;
  202. break;
  203. }
  204. current = current->next;
  205. }
  206. if(NULL != resnode)
  207. {
  208. CircleList_Delete(sList,i);
  209. }
  210. }
  211. return resnode;
  212. }
  213. //将游标重置回第一个元素
  214. CircleListNode* CircleList_Reset(CircleList* list)
  215. {
  216. TCircleList* sList = (TCircleList*)list;
  217. CircleListNode* ret = NULL;
  218. if( sList != NULL )
  219. {
  220. sList->sLider= sList->header.next;
  221. ret = sList->sLider;
  222. }
  223. return ret;
  224. }
  225. //获得当前游标下的结点
  226. CircleListNode* CircleList_Current(CircleList* list)
  227. {
  228. TCircleList* sList = (TCircleList*)list;
  229. CircleListNode* ret = NULL;
  230. sList->len;
  231. sList->header;
  232. sList->sLider;
  233. if( sList != NULL )
  234. {
  235. ret = sList->sLider;
  236. }
  237. return ret;
  238. }
  239. //将游标移到下一个结点并获得当前移动前的结点
  240. CircleListNode* CircleList_Next(CircleList* list)
  241. {
  242. TCircleList* sList = (TCircleList*)list;
  243. CircleListNode* ret = NULL;
  244. if( (sList != NULL) && (sList->sLider != NULL) )
  245. {
  246. ret = sList->sLider;
  247. sList->sLider = ret->next;
  248. }
  249. return ret;
  250. }

执行结果:

  1. 1
  2. 5
  3. 2
  4. 3
  5. 4
  6. 删除了:1
  7. 删除了:5
  8. 删除了:2
  9. 删除了:3
  10. 删除了:4
  11. 请按随意键继续. . .

如有错误,望不吝指出。

循环链表的实现与操作(C语言实现)的更多相关文章

  1. neo4j初次使用学习简单操作-cypher语言使用

    Neo4j 使用cypher语言进行操作 Cypher语言是在学习Neo4j时用到数据库操作语言(DML),涵盖对图数据的增删改查  neo4j数据库简单除暴理解的概念: Neo4j中不存在表的概念, ...

  2. 栈的实现与操作(C语言实现)

    栈的定义  1, 栈是一种特殊的线性表  2,栈仅能在线性表的一端进行操作  3,栈顶(Top): 同意操作的一端 同意操作的一端  4,栈底(Bottom): ,不同意操作的一端 不同意操作 ...

  3. 动态单链表的传统存储方式和10种常见操作-C语言实现

    顺序线性表的优点:方便存取(随机的),特点是物理位置和逻辑为主都是连续的(相邻).但是也有不足,比如:前面的插入和删除算法,需要移动大量元素,浪费时间,那么链式线性表 (简称链表) 就能解决这个问题. ...

  4. Gremlin--一种支持对图表操作的语言

    Gremlin 是操作图表的一个非常有用的图灵完备的编程语言.它是一种Java DSL语言,对图表进行查询.分析和操作时使用了大量的XPath. Gremlin可用于创建多关系图表.因为图表.顶点和边 ...

  5. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

  6. 双向链表的实现与操作(C语言实现)

    双向链表也叫双链表,是链表的一种,它的每一个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的随意一个结点開始,都能够非常方便地訪问它的前驱结点和后继结点. 单链表的局限 1.单 ...

  7. 图的存储结构与操作--C语言实现

    图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...

  8. 二叉树的操作--C语言实现

    树是一种比较复杂的数据结构,它的操作也比较多.常用的有二叉树的创建,遍历,线索化,线索化二叉树的遍历,这些操作又可以分为前序,中序和后序.其中,二叉树的操作有递归与迭代两种方式,鉴于我个人的习惯,在这 ...

  9. C文件操作的语言fgets()

        谈fgets(..)功能.     原型  char *  fgets(char * s, int n,FILE *stream);     參数:          s: 字符型指针.指向存 ...

随机推荐

  1. c++primer记录(二) 模板

    因为看得源码里有大量的类模板,所以补充下C++中模板的知识 模板:函数模板 类模板 .p- 函数模板的类型参数可由编译器进行推断,也可以由用户显式的指定,类模板的类型参数必须显式的给出: p- 非类型 ...

  2. Git 基础 - 查看提交历史

    查看提交历史 在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用 git log 命令查看. 接下来的例子会用我专门用于演示的 simplegit 项目,运行下面的命令获取该项目源 ...

  3. Learning Deep CNN Denoiser Prior for Image Restoration阅读笔记

    introduction 图像恢复目标函数一般形式: 前一项为保真项(fidelity),后一项为惩罚项,一般只与去噪有关. 基于模型的优化方法可以灵活地使用不同的退化矩阵H来处理不同的图像恢复问题, ...

  4. Linux中的SELinux详解--16

    SELinux 宽容模式(permissive) 强制模式(enforcing) 关闭(disabled)  几种模式之间的转换 在CentOS6.2 中安装intel 的c++和fortran 的编 ...

  5. HTML&CSS精选笔记_布局与兼容性

    布局与兼容性 CSS布局 版心和布局流程 为什么要应用布局? 阅读报纸时容易发现,虽然报纸中的内容很多,但是经过合理地排版,版面依然清晰.易读.同样,在制作网页时,要想使页面结构清晰.有条理,也需要对 ...

  6. Java精选笔记_Java编程基础

    Java的基本语法 Java代码的基本格式 修饰符 class 类名 {   程序代码 } 一个Java源文件只定义一个类,不同的类使用不同的源文件定义:将每个源文件中单独定义的类都定义成public ...

  7. 编译OSG的FreeType插件时注意的问题

    使用自己编译的freetype.lib,在编译osgdb_freetype插件项目时,报错LINK错误,找不到png的一堆函数 最简单的方式是不要使用PNG编译freetype.记住不要犯贱.

  8. CentOS6.5安装图形界面(Gnome)

    因为是以最小化安装的Linux,无法使用图形界面,从网上看到资料,我使用yum安装果然很简单 ----------------------------------------------------- ...

  9. 编写高性能的 Lua 代码

    前言 Lua是一门以其性能著称的脚本语言,被广泛应用在很多方面,尤其是游戏.像<魔兽世界>的插件,手机游戏<大掌门><神曲><迷失之地>等都是用Lua来 ...

  10. Apktool源码解析——第二篇

    上一篇讲到ApkDecoder这个类,大部分调用到还是Androlib类,而且上次发现brutall的代码竟然不是最新的,遂去找iBotP.的代码了. 今天来看Androlib的代码: private ...