约瑟夫环问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);

相关文档
最新文档