Linux C 数据结构—-循环链表

前面我们学习了单向链表,现在介绍单向循环链表,单向循环链表是单链表的一种改进,若将单链表的首尾节点相连,便构成单向循环链表结构,如下图:


     对于一个循环链表来说,其首节点和末节点被连接在一起。这种方式在单向和双向链表中皆可实现。要转换一个循环链表,可以选择开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点。再来看另一种方法,循环链表可以被视为“无头无尾”。这种列表很利于节约数据存储缓存, 假定你在一个列表中有一个对象并且希望所有其他对象迭代在一个非特殊的排列下。指向整个列表的指针可以被称作访问指针。
    循环链表中第一个节点之前就是最后一个节点,反之亦然。循环链表的无边界使得在这样的链表上设计算法会比普通链表更加容易。对于新加入的节点应该是在第一个节点之前还是最后一个节点之后可以根据实际要求灵活处理,区别不大。当然,如果只会在最后插入数据(或者只会在之前),处理也是很容易的。
      
      循环链表的应用

一、Joseph问题(约瑟夫环)

     据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人找到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。 

     约瑟夫环用数学问题来描述就是:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。如何用循环链表来求解Josephu问题?

    下面我们用单向循环链表来模拟这个问题:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. typedef int data_t;  
  5.   
  6. typedef struct node_t  
  7. {  
  8.     data_t data;  
  9.     struct node_t *next;      
  10. }linknode_t,*linklist;  
  11.   
  12. linklist CreateList(int n)  
  13. {  
  14.     int i;  
  15.     linklist p,head,tail;  
  16.     head = NULL;  
  17.       
  18.     for(i = 1;i <= n;i++)  
  19.     {  
  20.         p = (linklist)malloc(sizeof(linklist));  
  21.         if(p == NULL)  
  22.         {  
  23.             printf("malloc fails!\n");  
  24.         }  
  25.               
  26.         p->data = i;  
  27.         if(head == NULL)  
  28.         {  
  29.             head = p;  
  30.             tail = head;  
  31.         }  
  32.         else  
  33.         {  
  34.             tail->next = p;  
  35.         }                 
  36.           
  37.         tail = p;  
  38.     }  
  39.       
  40.     tail->next = head;  
  41.   
  42.     return head;   
  43. }  
  44.   
  45. void Joseph(int n,int k,int m)  
  46. {  
  47.     int i;  
  48.     linklist p,r;  
  49.     p = CreateList(n);  
  50.   
  51.     for(i = 1;i < k;i++) //从第K个人开始数  
  52.     {  
  53.         p = p->next;  
  54.     }  
  55.   
  56.     while(p->next != p)  
  57.     {  
  58.         for(i = 1;i <= m-2;i++)  //数到第m个人,去自杀  
  59.             p = p->next;  
  60.   
  61.         r = p->next;  
  62.         p->next = r->next;  
  63.         printf("%d->",r->data);  
  64.           
  65.         free(r);  
  66.         p = p->next;//从下一个人继续数  
  67.     }  
  68.       
  69.     printf("%d\n",p->data);  
  70. }  
  71.   
  72. int main()  
  73. {  
  74.     Joseph(41,1,3);  
  75.   
  76.     return 0;  
  77. }  
输出结果如下:
[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/linklist$ ./list1  
  2. 3->6->9->12->15->18->21->24->27->30->33->36->39->1->5->10->14->19->23->28->32->37->41->7->13->20->26->34->40->8->17->29->38->11->25->2->22->4->35->16->31  
我们可以看到,最后两个是16和31,这样,约瑟夫和他的朋友就躲过了一劫!


二、判断一个链表是不是循环链表(如何判定这个链表当中是否包含有环路

 解决方法:

      判断是否是循环链表时,也设置两个指针,慢指针和快指针,让快指针比慢指针每次移动快两次。如果快指针追赶上慢指针,则为循环链表,否则不是循环链表,如果快指针或者慢指针指向NULL,则不是循环链表。

代码如下:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. typedef int data_t;  
  5.   
  6. typedef struct node_t  
  7. {  
  8.     data_t data;  
  9.     struct node_t *next;      
  10. }linknode_t,*linklist;  
  11.   
  12. linklist CreateList(int n)  
  13. {  
  14.     int i;  
  15.     linklist p,head,tail;  
  16.     head = NULL;  
  17.       
  18.     for(i = 1;i <= n;i++)  
  19.     {  
  20.         p = (linklist)malloc(sizeof(linklist));  
  21.         if(p == NULL)  
  22.         {  
  23.             printf("malloc fails!\n");  
  24.         }  
  25.               
  26.         p->data = i;  
  27.         if(head == NULL)  
  28.         {  
  29.             head = p;  
  30.             tail = head;  
  31.         }  
  32.         else  
  33.         {  
  34.             tail->next = p;  
  35.         }                 
  36.           
  37.         tail = p;  
  38.     }  
  39.       
  40.     tail->next = head;  
  41.   
  42.     return head;   
  43. }  
  44.   
  45. int JudgeIsloop(linklist list)  
  46. {  
  47.     int flag = 0;  
  48.     linknode_t *slow,*fast;  
  49.   
  50.     if(list == NULL)  
  51.         return 0;  
  52.   
  53.     slow = list;  
  54.     fast = list->next;  
  55.   
  56.     while(slow)  
  57.     {  
  58.         if(fast == NULL || fast->next == NULL)//走到头了  
  59.             return 0;  
  60.         else if(fast == slow || fast->next == slow)//二者相遇,因为fast走的快,如果fast->next指向slow,也是循环的  
  61.         {     
  62.             flag = 1;  
  63.             return 1;  
  64.         }  
  65.         else  
  66.         {  
  67.             slow = slow->next;//慢指针走一步  
  68.             fast = fast->next->next;//快指针走两步  
  69.         }  
  70.     }  
  71.   
  72.     return 0;  
  73. }  
  74.   
  75. int main()  
  76. {  
  77.     int i;  
  78.     int flag = 0;  
  79.     linklist list;  
  80.     list = CreateList(10);  
  81.       
  82.     JudgeIsloop(list);  
  83.   
  84.     if(flag = 0)  
  85.         printf("The list is not a looplist!\n");  
  86.     else  
  87.     {  
  88.         printf("The list is a looplist!\n");//循环链表则打印出来  
  89.         for(i = 0;i < 10;i++)  
  90.         {  
  91.             printf("%d->",list->data);  
  92.             list = list->next;  
  93.         }  
  94.         printf("%d\n",list->data);  
  95.     }  
  96.   
  97.     return 0;  
  98. }  
结果如下:

[cpp] view plaincopy
  1. fs@ubuntu:~/qiang/linklist$ ./list2  
  2. The list is a looplist!  
  3. 1->2->3->4->5->6->7->8->9->10->1  
  4. fs@ubuntu:~/qiang/linklist$ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

预备作业03 20162320刘先润

第一次编代码 这几周自学了Linux基础入门&#xff0c;有好多想吐槽的地方&#xff0c;所以这篇随笔是带有半吐槽性质的&#xff0c;这是我学完后最真实的感受 我在电脑上按照教程安装了虚拟机&#xff0c;对于Linux这个完全陌生的概念也稍微算是有些理解&#xff0c;但是还有很…

JTable 失去焦点时取消编辑状态

为什么80%的码农都做不了架构师&#xff1f;>>> reference&#xff1a; http://tips4java.wordpress.com/2008/12/12/table-stop-editing/ 当JTable的单元格处于编辑状态时&#xff0c;如果用户触发以下事件&#xff0c;表格就会退出编辑状态&#xff0c;进而调用T…

JS中的array和Object的区别

区别&#xff1a; 数组表示有序数据的集合&#xff0c;对象表示无需数据的集合。如果数据顺序很重要的话&#xff0c;就用数组&#xff0c;否则就用对象的好。 数组的数据没有名称name 对象的数据有名称 name 但是在很多编程语言中有个叫关联数组的&#xff0c;这种数组中的…

Linux C 数据结构——栈

还是先把这张图贴出来&#xff0c;以便对比和理解 栈是限制在一段进行插入操作和删除操作的线性表&#xff08;俗称堆栈&#xff09;&#xff0c;允许进行操作的一端称为“栈顶”&#xff0c;另一固定端称为“栈底”&#xff0c;当栈中没有元素称为“空栈”。特点&#xff1a;先…

常用的HTTP状态码

2019独角兽企业重金招聘Python工程师标准>>> 第一、成功的状态码&#xff1a; 1&#xff09;200 OK – 服务器成功返回网页 2&#xff09;304 Not Modified – 未修改 第二、失败的状态码&#xff1a; 3&#xff09;404 Not F…

Linux C 数据结构——队列

还是先放这张图&#xff0c;以便对比和理解&#xff1a; 队列是限制在两端进行插入操作和删除操作的线性表&#xff0c;允许进行存入操作的一端称为“队尾”&#xff0c;允许进行删除操作的一端称为“队头”。当线性表中没有元素时&#xff0c;称为“空队”。特点&#xff1a;先…

MySQL视图查询报错:Prepared statement needs to be re-prepared

From: https://www.ywnds.com/?p12609 今天公司的项目视图查询报错&#xff0c;报错如&#xff1a;ERROR 1615 (HY000): Prepared statement needs to be re-prepared 网上找了一圈&#xff0c;都说调整以下值就好了&#xff1a; mysql> set global table_open_cache163…

如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间

1.安装FF的Firebug组件&#xff1a;点击FF的Tools的Add-ons菜单&#xff0c;输入Firebug关键字&#xff0c;并选择合适的版本Install。 2.安装完毕后地址栏右边会出现一个小虫图标&#xff0c;右边还有一个下拉箭头。如下图&#xff1a; 3.点击下拉箭头&#xff0c;选择“on fo…

Linux C 数据结构——二叉树

先放这张图&#xff1a; 可以看出&#xff0c;树是非线性结构&#xff1b; 一、树的概念 树&#xff08;tree&#xff09;是n(n>0)个节点的有限集合T&#xff0c;它满足两个条件&#xff1a; 1&#xff09;有且仅有一个特定的称为根&#xff08;root&#xff09;的节点&…

antd 表单域验证规则 - 只能输入数字字符,去除前导0

<Form {...formItemLayout}><Form.Item label用户Id>{getFieldDecorator(uid, {initialValue: undefined,rules: [{ required: true, message: 请输入用户id, pattern: new RegExp(/^[1-9]\d*$/, g) }],getValueFromEvent: e > e.target.value.replace(/\D/g, )…

2013 822 划分子网

子网的划分是为了节省我们的网络的ip地址的分配,如我们有200台电脑需要一个子网段,我在这个192.168.0.1网段我们有254个地址,我们可以将我们的计算机划分成不同的子网,来进行使用,这样的话就是节省了大量的IP地址.补充下上次忘记总结的东西,就是如192.168.10.101/24 24表示我们…

BZOJ 3224: Tyvj 1728 普通平衡树

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9629 Solved: 4091[Submit][Status][Discuss]Description 您需要写一种数据结构&#xff08;可参考题目标题&#xff09;&#xff0c;来维护一些数&#xff0c;其中需要提供以下操作&#xff1a;…

springboot中配置mybatis数据源,使用阿里的 Druid 数据库连接池

参考了很多文章&#xff0c;记录下自己的学习过程&#xff01; 参考&#xff1a;https://blog.csdn.net/weixin_40776321/article/details/99633110 1. 在pom.xml中添加依赖&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>dr…

Linux C 算法——查找

所谓“查找”记为在一个含有众多的数据元素&#xff08;或记录&#xff09;的查找表中找出某个“特定的”数据&#xff0c;即在给定信息集上寻找特定信息元素的过程。 为了便于讨论&#xff0c;必须给出这个“特定的”词的确切含义。首先&#xff0c;引入一个“关键字”的概念&…

SharePoint项目中新建类库的错误处理及项目建设中遇到的问题总结

第一次SP项目总监遇到各种问题&#xff0c;以下是总结&#xff1a;问题1.创建SP项目的时候“场解决方案”跟“沙盒解决方案”是有区别的&#xff0c;具体可以看MSDN官方文档&#xff0c;这里简单摘抄如下&#xff1a;1&#xff09;场解决方案&#xff1a;承载与W3WP.exe中&…

ECharts学习(1)--简单图表的绘制

1.获取ECharts 官网 下载&#xff1a;http://echarts.baidu.com/download.html 2.在html页面中引入ECharts文件 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>ECharts练习</title><script type"text/javas…

php配置xdebug断点调试

环境&#xff1a;mac 10.15.4 zcmzcmdeMacBook-Pro 20190902 % php -v PHP 7.4.9 (cli) (built: Aug 7 2020 19:23:06) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologieswith Xdebug v2.9.6, Copyright (c) 2002-2020, by Derick R…

Linux C 算法——排序

排序(Sort)是将无序的记录序列&#xff08;或称文件&#xff09;调整成有序的序列。 为了方便讨论&#xff0c;在此首先要对排序下一个确切的定义&#xff1a; 假设含有n个记录的序列为 { R1、R2、&#xff0c;。。。Rn } 其相应的关键字序列为 {K1、K2&#xff0c;。。。。Kn}…

HTTP错误代码

服务器错误代码大全 400 - 错误的请求。 401 - 访问被拒绝。IIS 定义了许多不同的 401 错误&#xff0c;它们指明更为具体的错误原因。这些具体的错误代码在浏览器中显示&#xff0c;但不在 IIS 日志中显示&#xff1a; 401.1 - 登录失败。 401.2 - 服务器配置导致登录失败。 4…

UIKit封装的系统动画

简介 在UIKit中&#xff0c;对UIView封装了很多类方法来进行简单的动画实现&#xff0c;在动画过程中&#xff0c;通过对属性值的修改来完成一系列的效果。 在IOS4以前&#xff0c;主要通过 beginAnimation setAnimationDuration:设置动画时长 setAnimationDelay:设置延迟时…