|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 moc 于 2018-9-24 11:10 编辑
1、基本概念
循环单链表的定义:将单链表中的最后一个元素的next指向第一个元素。
注意:头指针是链表的开始,它的指针域指向头结点,数据域存放着与整个链表相关的数据,如长度等;头指针结点不参与链表循环。
拥有的操作:
创建链表
销毁链表
获取链表长度
清空链表
获取链表的第pos个元素
插入元素到pos位置
删除pos位置的元素
新增功能: 游标
在循环链表中可以定义一个“当前”指针,这个指针即通常称的“游标”,可以通过游标来遍历元素。
循环链表的新增操作:
将游标重置,即指向链表的第一个元素;
获取当前游标指向的数据元素;
将游标移动至下一个元素;
直接指定删除链表中的某个数据元素。
2、设计与实现
1. 插入元素
① 普通插入元素: 和单链表一样
② 尾插法: 和单链表一样
③ 头插法: 需要先求出尾结点,因为0号位置,辅助指针current跳0步,没有跳走仍留在头指针。
④ 判断若为第一次插入,让游标指向头结点。
- void CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
- {
- int ret = 0, i = 0;
- TCircleList* tlist = (TCircleList*)list;
- if (tlist == NULL || node == NULL || pos < 0)
- {
- return -1;
- }
- CircleListNode* current = (CircleListNode*)tlist;
- for (i = 0; (i < pos) && (current->next != NULL); i++)
- {
- current = current->next;
- }
- node->next = current->next; // 1
- current->next = node; // 2
- // 若第一次插入
- if (tlist->length == 0)
- {
- tlist->slider = node;
- }
- tlist->length++;
- // 若头插法 current仍然指向头部
- //(原因:跳0步,没有跳走仍留在头指针,导致尾部指针指向第二个结点)
- if (current == (CircleListNode*)tlist)
- {
- CircleListNode* last = CircleList_Get(tlist, tlist->length - 1);
- last->next = current->next;
- }
- }
复制代码
2. 其他操作与单链表类似。
3、优缺点与典型应用
优点:
循环单链表在单链表的基础上功能增强啦;
完全可以替代单链表。
缺点:
代码复杂度提高啦。
约瑟夫问题:
n个人围成一个圆圈,首先第一个人从1开始一个人一个人顺时针报数,报到第m个人,令其出列,然后从下一个人开始顺时针报数,报到第m个人,再令其出列,....,如此下去,求出出列顺序。
循环链表解决方案:
- typedef struct _Value
- {
- CircleListNode circleNode;
- int v;
- }Value;
- int main()
- {
- int i = 0;
- CircleList* list = CircleList_Create();
- Value v1, v2, v3, v4, v5, v6, v7, v8;
- v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4;
- v5.v = 5; v6.v = 6; v7.v = 7; v8.v = 8;
- CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v5, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v6, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v7, CircleList_Length(list));
- CircleList_Insert(list, (CircleListNode*)&v8, CircleList_Length(list));
- for (i = 0; i < CircleList_Length(list); i++)
- {
- // 获取游标所指的元素,然后游标下移
- Value* pv = (Value*)CircleList_Next(list);
- printf("%d\n", pv->v);
- }
- printf("\n");
- // 重置游标
- CircleList_Reset(list);
- while (CircleList_Length(list) > 0)
- {
- Value* pv = NULL;
- for (i = 0; i < 2; i++)
- {
- CircleList_Next(list);
- }
- pv = (Value*)CircleList_Current(list);
- printf("%d\n", pv->v);
- CircleList_DeleteNode(list, (CircleListNode*)pv);
- }
- CircleList_Destory(list);
- system("pause");
- return 0;
- }
复制代码
完整代码:
循环单链表.zip
(2.27 KB, 下载次数: 13)
|
|