约瑟夫环
a) 问题描述:Joseph问题的一种描述是:编号为1、2、……、n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
b) 基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
c) 测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先报m的人
为6(正确的出列顺序应为6,1,4,7,2,3,5)。
实现提示:程序运行后,首先要求用户指定初始报数上限值,然后读取各人的密码。可设n <=30。
*/
#include"stdio.h"
#include"malloc.h"
typedef int Datatype; //定义单链表结点
typedef struct node
{ Datatype code;
Datatype num;
struct node *next;
}Linklist;
Linklist *creatsclist(int x) //***
{ Linklist *p,*q,*H;
int i,code;
i=1; //
/*printf("请输入第%d人的密码:",i);scanf("%d",&code);printf("\n");*/
H=(Linklist *)malloc(sizeof(struct node));
H->next=NULL; //i++;
p=H;
while(i<=x)
{ //
printf("请输入第%d人的密码:",i);scanf("%d",&code);printf("\n");
q=(Linklist *)malloc(sizeof(struct node));
q->code=code;
q->num=i;
q->next=NULL;
p->next=q;
p=q; i++;
}
q->next=H->next; //尾结点链接到头结点的下一结点
return H;
}
void printlist(Linklist *H,int x)
{ Linklist *p; int i=1;
p=H->next;
if(p!=NULL)
while(i<=x)
{ printf("%d,%d\t",p->num,p->code);
p=p->next;
i++;
}
printf("\n\n");
}
void Joseph(Linklist *H)
{ Linklist *p,*q,*v;
int m,k; k=0;
p=H->next; q=H; //
printf("请输入报数上限值:"); scanf("%d",&m); printf("\n");
while(p!=q) //
{ k++; //
if(k==m)
{ printf("%d\t",p->num);
m=p->code; k=1;
if(H->next==p) H->next=p->next; //该处易出问题
q->next=p->next; //
v=p;
p=q->next; free(v);
}
q=p; //
p=p->next;
}
printf("%d\t",p->num);
printf("\n");
}
void main()
{ Linklist *H;
int x;
printf("请输入总人数:"); scanf("%d",&x); printf("\n");
H=creatsclist(x);
printf("输出每个人的编号,密码:\n");
printlist(H,x);
printf("约瑟夫环问题结果输出:\n");
Joseph(H);
}
本文来源:https://www.2haoxitong.net/k/doc/c250490ebb68a98271fefab4.html
文档为doc格式