双链表应用之约瑟夫环问题
来源:互联网 发布:linux定时执行脚本 编辑:程序博客网 时间:2024/05/21 19:14
约瑟夫约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围,从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从1~n,最后结果即为原问题的解。
在下面的例子中,我就先以5人的约瑟夫环进行测试:
约瑟夫环问题,你可以用顺序表解决,你也可以用双链表来解决,在时间复杂度上,毋庸置疑,肯定是双莲表复杂度底,那就以双链表为例吧!
假设你拿到一个已经初始化的双链表,那么肯定对这个双链表加工成为环:只需标记尾部tmp,然后tmp->next = phead->next; phead->next->pre = tmp;这一步主要让双联表成环。下来就是杀人了。
假设是第一个人,报数从1开始,每次报到 m 的人就被杀死,对应到链表里就是每走 m-1 步后指向的结点被删除,(用简单的5个人,报到3的人退出,p刚开始指向头节点的下个结点--首元结点,p往后走2步,到达的结点就该被删除,)
最后你这个循环的终止条件为4自己指向自己或者phead的id变成计数,
phead->id == 1终止,那么就剩代码了!
代码:
D_JOSEPH.h
#ifndef _D_JOSEPH_H_#define _D_JOSEPH_H_typedef int elem_type;typedef struct _NODE {elem_type id;struct _NODE *next;struct _NODE *pre;}NODE;NODE * init_double_list();bool insert_head(NODE *phead,elem_type id);NODE *CreateLoopList(int num);int Kill(NODE *phead, int gap);#endif
D_JOSEPH.cpp
#include"D_JOSEPH.h"#include<stdio.h>#include<stdlib.h>#include<assert.h>#define ERROR -1static int getlength(NODE *phead){NODE *p = phead;int i = 0;if(phead == NULL){return ERROR;}while(p->next){i++;p = p->next;}return i;}static NODE *alloc(elem_type e){NODE *tmp = (NODE *)malloc(sizeof(NODE));assert(tmp != NULL);tmp->id = e;tmp->next = NULL;tmp->pre = NULL;return tmp;}NODE * init_double_list(){NODE *phead = (NODE *)malloc(sizeof(NODE));assert(phead != NULL);phead->id = 0;phead->next = NULL;phead->pre = NULL;return phead;}bool insert_head(NODE *phead,elem_type id){NODE *tmp = alloc(id);if(phead == NULL){return false;}tmp->next = phead->next;if(phead->next != NULL)//是空表{phead->next->pre = tmp;}phead->next = tmp;tmp->pre = phead;phead->id ++;return true;}NODE *CreateLoopList(int num){NODE *phead = init_double_list();NODE *tmp = alloc(num); phead->next = tmp;tmp->pre = phead;phead->id ++;for(int i = num-1;i>= 1;i --){insert_head(phead,i);}tmp->next = phead->next;//双链表成环phead->next->pre = tmp;return phead;}int Kill(NODE *phead, int gap){NODE *p = phead->next;NODE *s = phead->next;if(phead == NULL){return ERROR;}while(p->next != p){for(int i = 0;i < gap-1;i ++){p = p->next;}s = p;p->pre->next = p->next;p->next->pre = p->pre;p = p->next;printf("id-%d被杀\n",s->id);phead->id--;free(s);}int rs = p->id;free(p);free(phead);return rs;}main.cpp
#include<stdio.h>#include"D_JOSEPH.h"int main(){int m = 13;//总数int ag = 3;//按照多少来报数NODE *phead = CreateLoopList(m);//成环函数int i = Kill(phead,3);printf("最后活着的人id-%d\n",i);return 0;}结果:
1 0
- 双链表应用之约瑟夫环问题
- 约瑟夫环应用问题
- 数据结构之顺序表应用-----《约瑟夫问题》
- c之约瑟夫环问题
- 约瑟夫问题、约瑟夫环
- 约瑟夫环的问题与应用(JAVA)
- 线性表应用_约瑟夫环问题
- 循环链表应用之约瑟夫环
- 数据结构之线性表——约瑟夫环问题(循环链表的应用)
- JavaScript数据结构之单向循环链表应用-约瑟夫问题
- 数学问题(三)之 约瑟夫环
- 赌博算法之约瑟夫环问题(JAVA)
- 经典算法之约瑟夫环问题
- 约瑟夫环问题之选猴王
- 【剑指offer】之约瑟夫环问题
- 算法学习笔记之约瑟夫环问题
- 链表面试题之约瑟夫环问题
- 算法学习之约瑟夫环问题
- android studio 快捷键
- 区别==和equals和String创建的区别
- UML学习一 初识建模
- 深入理解CUDA线程层次以及关于设置线程数的思考
- DVD管理!!
- 双链表应用之约瑟夫环问题
- 学习IO流之File类和Files类的使用
- 第四周name
- 学习IO流之字节流和字符流
- 微服务产品级敏捷: 微服务架构设计
- PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别
- 【JZOJ4799】【NOIP2016提高A组模拟9.24】我的快乐时代
- 1加到n
- 回忆java来时路-第七章 类的初始化