设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,
然后从出列的下一个人重新开始报数,数到第m的人又出列……如此反复直到所有的人全部
出列为止。Josephus问题是:对于任意给定的n,s,m,求出按出列次序得到的n个人员的序列。
struct child
{
char *name;
child *next;
};
child* initchild(char *stu[],int n) //初始化链表函数
{
child *p,*head=NULL,*q,*last;
if(stu!=NULL)
{
int i=0;
while(n>0)
{
head=(child *)malloc(sizeof(child));
head->name=stu[n-1];
n=n-1;
p=head;
if(i==0)
{
p->next=head;
q=p;
last=p; //标志尾部节点
i++;
}
else
{
p->next=q;
q=p;
}
}
last->next=head;
}
return head;
}
void josephus(int n,int s,int m,char *stu[])
{
if(s>n||s==0)
{
printf("s不能大于n或者s要不等于0");
return;
}
child * head = initchild(stu,n);//初始化链表
child *p,*q,*pre;
p=head;
q=head;
pre=head;
int i,j,k;
for(i=0;i<s-1;i++) //找开始报数的人
{
pre=p;
q=p->next;
p=q;
}
int count=0;
while(count!=n) //出对人数等于n 结束
{
if(n==1)
{
printf("出对顺序为:%s/n",head->name);
return;
}
for(j=0;j<m-1;j++) //找出对的人
{
pre=p;
q=p->next;
p=q;
}
count++;
q=p->next;
pre->next=q;
if(count==n)
printf("%s/n",p->name);
else
{
printf("%s-->",p->name);
}
delete p;
p=q;
}
}