约瑟夫环问题的解决
2015-06-12 20:37
204 查看
约瑟夫环问题介绍:
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
链表初始状态:
刚开始写这个程序的时候,遇到一个Bug,那就是没有解决链表丢失问题。比如当退出的节点刚好为1号节点时
,1号节点就会被Free掉,这样就不能通过phead来访问各个节点了,整个链表就丢失了。
于是我在DeleteNode()函数里加了一个判断:当删除节点为第一个数据节点时,更改头节点的指针域的值,
使指向第一个数据节点的下一个节点,这样链表就不会丢失了。
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
# include <stdio.h> # include <stdlib.h> # include <assert.h> typedef int DataTp; typedef struct node { DataTp elem; struct node*pnext; }NODE; typedef NODE* LinkList; NODE* CreatList(int n); void MakeLoop(LinkList phead); void DeleteNode(LinkList phead,LinkList paim); int main (void) { int sum,num; //总人数 , 退出人的编号 int i; LinkList pstart; //头节点 LinkList paim; //待删除的目标节点的地址 LinkList pt; puts("输入总人数"); scanf("%d",&sum); puts("输入退出的编号"); scanf("%d",&num); pstart=CreatList(sum); //建立链表 MakeLoop(pstart); //变为循环链表 pt=pstart->pnext; //取出第一个数据节点地址 while(sum!=0) { for(i=0;i<num-1;i++) pt=pt->pnext; //往后寻址,找到退出目标的地址 paim=pt; //临时保存。确定删除节点的地址 pt=pt->pnext; //确定下次循环的头为pt printf("退出的是%d号\n",paim->elem); DeleteNode(pstart,paim); //删除 sum--; //总人数减少 } return 0; } NODE* CreatList(int n) { int i; NODE*p1,*p2; NODE * phead; phead=(NODE*)malloc(sizeof(NODE)); if(phead==NULL) { fputs("memory error!\n",stderr); exit(EXIT_FAILURE); } phead->pnext=NULL; ///////////////////////////////// for(i=0;i<n;i++) { p1=(NODE*)malloc(sizeof(NODE)); //分配内存 if(p1==NULL) //检查合法性 { fputs("memory error!\n",stderr); exit(EXIT_FAILURE); } p1->elem=i+1; //补全结点信息 p1->pnext=NULL; if(phead->pnext==NULL) //链接 phead->pnext=p1; else p2->pnext=p1; p2=p1; //重置 } return phead; } void MakeLoop(LinkList phead) { NODE*p=phead->pnext; //取出第一个数据节点 assert(p!=NULL); while(p->pnext!=NULL) p=p->pnext; p->pnext=phead->pnext; // 链接,构成循环链表 return ; } void DeleteNode(LinkList phead,LinkList paim) { NODE*p=phead->pnext; //取出第一个数据节点 assert(p!=NULL); while(p->pnext!=paim) p=p->pnext; p->pnext=p->pnext->pnext; if(paim==phead->pnext) //如果删除的是第一个数据节点, phead->pnext=p->pnext; //改变头节点指针域的值,使它始终指向 //循环链链表的某一个节点。而不丢失链表节点 free(paim); return ; }
链表初始状态:
刚开始写这个程序的时候,遇到一个Bug,那就是没有解决链表丢失问题。比如当退出的节点刚好为1号节点时
,1号节点就会被Free掉,这样就不能通过phead来访问各个节点了,整个链表就丢失了。
于是我在DeleteNode()函数里加了一个判断:当删除节点为第一个数据节点时,更改头节点的指针域的值,
使指向第一个数据节点的下一个节点,这样链表就不会丢失了。
相关文章推荐
- 月计划表
- 如何实现共享软件网络授权认证,包括注册新用户、登录、修改密码等操作
- CSS3之文本相关样式
- [Swust OJ 188]--异面空间(读懂题意很重要)
- user agent stylesheet 解决方法
- 设计一个算法,判断字符串S是否对称
- 缓存和缓冲的区别
- HMMSearchState API
- Binary Tree
- 三次方格取数
- Binary Tree 分类: POJ 2015-06-12 20:34 17人阅读 评论(0) 收藏
- 统计输入的字符串各个不同字符出现的频度,并存入文件,合法字符为:“A~Z”和“0~9”
- 6.12
- WordSearchState API
- asp.net mvc 中使用日期控件(My97DatePicker)(一)
- cocos2d-x项目打包成exe文件后的音乐无法播放问题
- Winform开发框架中实现同时兼容多种数据库类型处理
- Linguist API 语言专家
- SearchGraph API
- linux 命令——ls