约瑟夫环问题:
问题描述:编号为1,2,...,n的n个人按顺时针方向围坐在一张圆桌周围,每个人持有一个密码。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向从1开始报数,报道m时停止报数,报m的人出列,将他的密码作为新的m值,从他顺时针的下一个人开始报数,直到所有的人都出列。
算法的分析:
由于该游戏中是一个循环的过程,可以每个人视为一个结点,结点中的数据部分为每个人的编号和密码,指针部分存放下一个结点的地址信息,那么该问题可以采用单向循环链表的数据结构进行解决。
1)定义结构体
typedef struct lnode
{
int id;
int passwd;
struct lnode *next;
}lnode,linklist*;
2)创建循环链表
采用尾插法;
3)从链表中寻找第M个结点并删除该结点
void JosephusOprate( )
{
int count=0;
int flag=1;
lnode *p,*q,*d;
linklist head;
p=q=head;
while(p->next!=head)
p=p->next;
while(flag)
{
for(int i=1;i<m;i++)
{
p=q;
q=q->next;
}
if(p==q) flag=0;
d=q;
m=d->passwd;
p->next=q->next;
q=q->next;
free(d);
}