约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列,输出最后一个出列的人的编号,猴王问题也是和这个思路一样的,都可采用循环链表来实现。
typedef struct kil
{
int number;
struct kil *next;
}*link;
void Init(link &Q)
{
Q=(link)malloc(sizeof(kil));
Q->next=NULL;
}
void Creat(link &Q,int n)
{
int count=1;
link p;
link p0;
p0=Q;
while(count-1 !=n)
{
if(count==1)
{
Q->number=count++;
}
else
{
Init(p);
p->number=count++;
p0->next=p;
p0=p;
}
}
p0->next=Q;<span style="white-space:pre"> </span>//建立循环单链表
}
void Print(link Q)
{
link p;
printf("%4d",Q->number);
p=Q->next;
while(p !=Q)
{
printf("%4d",p->number);
p=p->next;
}
cout<<endl;
}
void Kiled(link &Q,int m)
{
int count;
link p,p0,pp;
p=Q;
printf("杀的人的编号为:");
while( p->next != p) // 1
{
count=1;
while(count<m)
{
p0=p;
p=p->next;
count++;
}
if(count==m)
{
p0->next=p->next;
printf("%4d",p->number);
pp=p;
p=p->next;
free(pp);
}
}
Q=p;
}
int main()
{
int n,m;
link Q;
Init(Q);
cout<<"总人数,编号:";
cin>>n>>m;
Creat(Q,n);
Print(Q);
Kiled(Q,m);
cout<<endl;
cout<<"最后那个人的编号为:";
cout<<Q->number<<endl;
return 0;
}
注释1中也可以这样来写代码
for(int i=1;i<=n-1; i++)
{
count=1;
while(count<m)
{
p2=p1;
p1=p1->next;
count++;
}
cout<<p1->number<<"\t";
p=p1;
p2->next=p1->next;
p1=p1->next;
free(p);
}
由n个人组成的环,需要循环n-1次。