//约瑟夫环问题的一种描述是:编号为1,2,3,n的n个人按顺时针围坐一圈,每人持有一个密码(正整数),一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方//向自1开始报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人出列为止。试设计///一个程序求出列顺序.
//测试数据:m的初值为20,n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6,正确的顺序应是6,1,4,7,2,3,5.
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
int number;
int key;
struct node* next;
}listnode, * circularlist;//定义了结点类型listnode和指针类型circularlist
int main()
{
int amount,t,code,m,k;// amount表示总人数,code表示相应的学生密码
circularlist w=(listnode*)malloc(sizeof(listnode));
w->next=w;//循环链表仅一个元素时依然满足
listnode *v;
printf("请输入总人数:");
scanf("%d",&amount);
v=w;
for(k=1;k<=amount;k++)
{
printf("请输入第 %d学生的密码: ",k);
scanf("%d",&code);
w->key=code;
w->number=k;
if(k!=amount)
{
w->next=(listnode*)malloc(sizeof(listnode));
w=w->next;
}
w->next=v;
}//循环结束后自动生成链表头
printf("约瑟夫环已建成,可以开始!\n");
printf("请输入初值: ");
scanf("%d",&m);
if(m<=0)
{
printf("输入错误,请重新输入\n");
return(1);
}
m=m-1;//使w提前停下
printf("出列顺序是: ");
//用w为起始点
do
{
t=0;//加入m减1后为零的情况
while(t!=m)
{
w=w->next;
t++;
}
v=w->next;
w->next=v->next;
printf(" %d",v->number);
m=v->key;
m=m-1;
free(v);//释放v的存储空间
}while(w->next!=w);
printf(" %d\n",w->number);
free(w); //释放w的存储空间
getchar();
getchar();
return(0);
}