约瑟夫环问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验题目:
约瑟夫环问题。
二、实验内容:
设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一个正整数密码。开始时任选一个正整数做为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m是停止报数,报m 的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数。如此下去,直到所有人全部出列为止。令n最大值取30。要求设计一个程序模拟此过程,求出出列编号序列。
实现:用一个不带头结点的单向循环链表表示上述约瑟夫环,结点结构可定义为:
typedef struct node{ Array int pos;//位置
int code;//密码
struct node *next;
}JosephNode,* JosephList;;
三、程序源代码:
# include
# include
# define ERROR 0
# define OK 1
Typedef struct node{
int pos,code;
struct node *next;
}JosephNode,* JosephList;
int InitList_Joseph(JosephList &h,int n)
//初始Joseph环。//为什么就&h,而不是h??
{ JosephNode *newp,*p;
h=NULL;
for(int i=1;i<=n;i++)
{ newp=(JosephList)malloc(sizeof(JosephNode));
if(!newp)
return ERROR;
newp->pos=i;
printf("Please input the %dth one's code\n ",i);
scanf("%d",&newp->code);
if(h==NULL)
{h=newp;p=newp;}
else
{p->next=newp;
p=newp;
}
}
p->next=h;return OK;
}
int length(JosephList &h)
//求Joseph环的长度。
{ int len=0;JosephList ph=h;
if(h==NULL) return (len=0);
if(ph->next==ph) return (len=1);
while(ph->next !=h)
{len++;ph=ph->next;}
len++;
return len;
}
//////
void print(JosephList h)
//输出Joseph环。
{ JosephList ph=h;
system("CLS");
printf("The length of Joseph Circle is %d!\n",length(h));
if(ph==NULL){printf("This Joseph circle is empty!\n");return;}
do
{ printf("%dth one's code is %d\n",ph->pos,ph->code);
ph=ph->next;
}while(ph!=h);
}
//////
void Push_Joseph(JosephList h,int m)
//用递归方法求其出圈顺序。
{ JosephList p,first,pf;
static int cnt=0;
if(m==0){printf("\n\nCODE ERROR(0 inluded)\n\n");return;}//若code为0则出错,退出!
if(length(h)<=1)//当长度为1时,最后一个节点出圈。结束函数。
{printf("\nThe last one is %d\n",h->pos); return;}
else
{ p=h;pf=p;
if(m==1)////若m==1则出圈的是其自己.
{ while(p->next!=h)
p=p->next; //找到其前驱。
printf("\nthe %dth one is %d",++cnt,h->pos);
p->next=h->next;
m=h->code;
free(h);
first=p->next;//将其后继当作头节点,
Push_Joseph(p,m);//递归调用Push_Joseph.
}
else//若m>1则,依次报数。
{for(int i=1;i { pf=p;p=p->next;} printf("\nThe %dth one is %d",++cnt,p->pos);//让其出圈。 pf->next=p->next; m=p->code; first=p->next; //将其后继当作头节点, free(p); Push_Joseph(first,m);//递归调用Push_Joseph. } } } void main() { int n,m; JosephList h=NULL; printf("Please input the number of people.\n"); scanf("%d",&n); printf("h=%d\n",h); if(!InitList_Joseph(h,n))//判断初始环是否成功。 {printf("Creating Joseph circle fails\n");exit(0);} print(h);//输出Joseph圈。 printf("Please input the first number!\n"); scanf("%d",&m);