鱼C论坛

 找回密码
 立即注册
查看: 1967|回复: 0

[学习笔记] 004-循环单链表

[复制链接]
发表于 2018-9-24 10:19:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 moc 于 2018-9-24 11:10 编辑

1、基本概念
循环单链表的定义:将单链表中的最后一个元素的next指向第一个元素。
8.jpg

        注意:头指针是链表的开始,它的指针域指向头结点,数据域存放着与整个链表相关的数据,如长度等;头指针结点不参与链表循环。
拥有的操作:
        创建链表
        销毁链表
        获取链表长度
        清空链表
        获取链表的第pos个元素
        插入元素到pos位置
        删除pos位置的元素
新增功能: 游标
        在循环链表中可以定义一个“当前”指针,这个指针即通常称的“游标”,可以通过游标来遍历元素。
循环链表的新增操作:
        将游标重置,即指向链表的第一个元素;
        获取当前游标指向的数据元素;
        将游标移动至下一个元素;
        直接指定删除链表中的某个数据元素。
2、设计与实现
1. 插入元素
        ① 普通插入元素:  和单链表一样
        ② 尾插法: 和单链表一样
        ③ 头插法: 需要先求出尾结点,因为0号位置,辅助指针current跳0步,没有跳走仍留在头指针。
        ④ 判断若为第一次插入,让游标指向头结点。
76.jpg

  1. void CircleList_Insert(CircleList* list, CircleListNode* node, int pos)
  2. {
  3.         int ret = 0, i = 0;
  4.         TCircleList* tlist = (TCircleList*)list;
  5.         if (tlist == NULL || node == NULL || pos < 0)
  6.         {
  7.                 return -1;
  8.         }

  9.         CircleListNode* current = (CircleListNode*)tlist;
  10.         for (i = 0; (i < pos) && (current->next != NULL); i++)
  11.         {
  12.                 current = current->next;
  13.         }

  14.         node->next = current->next;  // 1
  15.         current->next = node;  // 2

  16.         // 若第一次插入
  17.         if (tlist->length == 0)
  18.         {
  19.                 tlist->slider = node;
  20.         }
  21.         tlist->length++;

  22.         // 若头插法 current仍然指向头部
  23.         //(原因:跳0步,没有跳走仍留在头指针,导致尾部指针指向第二个结点)       
  24.         if (current == (CircleListNode*)tlist)
  25.         {
  26.                 CircleListNode* last = CircleList_Get(tlist, tlist->length - 1);
  27.                 last->next = current->next;
  28.         }
  29. }
复制代码

2. 其他操作与单链表类似。
3、优缺点与典型应用
优点:
        循环单链表在单链表的基础上功能增强啦;
        完全可以替代单链表。
缺点:
        代码复杂度提高啦。
约瑟夫问题:
        n个人围成一个圆圈,首先第一个人从1开始一个人一个人顺时针报数,报到第m个人,令其出列,然后从下一个人开始顺时针报数,报到第m个人,再令其出列,....,如此下去,求出出列顺序。
77.jpg

循环链表解决方案:
  1. typedef struct _Value
  2. {
  3.         CircleListNode circleNode;
  4.         int v;
  5. }Value;

  6. int main()
  7. {
  8.         int i = 0;
  9.         CircleList* list = CircleList_Create();
  10.         Value v1, v2, v3, v4, v5, v6, v7, v8;
  11.         v1.v = 1;  v2.v = 2;  v3.v = 3;  v4.v = 4;
  12.         v5.v = 5;  v6.v = 6;  v7.v = 7;  v8.v = 8;

  13.         CircleList_Insert(list, (CircleListNode*)&v1, CircleList_Length(list));
  14.         CircleList_Insert(list, (CircleListNode*)&v2, CircleList_Length(list));
  15.         CircleList_Insert(list, (CircleListNode*)&v3, CircleList_Length(list));
  16.         CircleList_Insert(list, (CircleListNode*)&v4, CircleList_Length(list));
  17.         CircleList_Insert(list, (CircleListNode*)&v5, CircleList_Length(list));
  18.         CircleList_Insert(list, (CircleListNode*)&v6, CircleList_Length(list));
  19.         CircleList_Insert(list, (CircleListNode*)&v7, CircleList_Length(list));
  20.         CircleList_Insert(list, (CircleListNode*)&v8, CircleList_Length(list));

  21.         for (i = 0; i < CircleList_Length(list); i++)
  22.         {
  23.                 // 获取游标所指的元素,然后游标下移
  24.                 Value* pv = (Value*)CircleList_Next(list);
  25.                 printf("%d\n", pv->v);
  26.         }
  27.         printf("\n");

  28.         // 重置游标
  29.         CircleList_Reset(list);

  30.         while (CircleList_Length(list) > 0)
  31.         {
  32.                 Value* pv = NULL;
  33.                 for (i = 0; i < 2; i++)
  34.                 {
  35.                         CircleList_Next(list);
  36.                 }
  37.                 pv = (Value*)CircleList_Current(list);
  38.                 printf("%d\n", pv->v);
  39.                 CircleList_DeleteNode(list, (CircleListNode*)pv);
  40.         }

  41.         CircleList_Destory(list);

  42.         system("pause");
  43.         return 0;
  44. }
复制代码

完整代码: 循环单链表.zip (2.27 KB, 下载次数: 13)

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 20:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表