实验一约瑟夫环问题
约瑟夫环问题:
设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一个正整数密码。
开始时任选一个正整数做为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m是停止报数,报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数。
如此下去,直到所有人全部出列为止。
令n最大值取30。
要求设计一个程序模拟此过程,求出出列编号序列。
实现:
用一个不带头结点的单向循环链表表示上述约瑟夫环,结点结构可定义为:
typedef sturct node Array { int no; /*编号*/
int key; /*密码域*/
struct node *next; /*指针域*/
} jNode;
注意:
不带头结点的单向循环链表判空条件的处理。
#include<stdio.h>
#include<stdlib.h>
typedef struct Joseph
{
int num;
int key;
struct Joseph *next;
} Joseph1;
Joseph1 *CreatList(int n)
{
Joseph1 *R,*p,*q;
int i,k;
R=p=(Joseph1*)malloc(sizeof(Joseph1));
p->next=NULL;
for(i=0;i<n-1;i++){
q=(Joseph1*)malloc(sizeof(Joseph1));
p->num=i+1;
scanf("%d",&k);
if(k<=0)
{
printf("输入信息有误!");
exit(0);
}
p->key=k;
p->next=q;
p=q;
}
q->num=n;
scanf("%d",&k);
if(k<=0)
{
printf("输入信息有误!");
exit(0);
}
q->key=k;
q->next=R;
R=q;
return(R);
}
void DeleList(int n,Joseph1 *P,int m)
{
Joseph1 *q,*t;
q=P;
int i,j;
for(i=1;i<n;i++)
{
for(j=1;j<m;j++)
q=q->next;
t=q->next;
q->next=t->next;
m=t->key;
printf("删除的第%d个数是:",i);
printf("%d\n",t->num);
free(t);
}
printf("删除的最后一个数是:%d\n",q->num);
free(q);
}
void main()
{
int m,n;
Joseph1 *P;
printf("请输入参加的人数: ");
scanf("%d",&n);
if(n<=0|)
{
printf("输入信息有误!");
exit(0);
}
printf("请输入初始密码: ");
scanf("%d",&m);
if(m<=0)
{
printf("输入信息有误!");
exit(0);
}
printf("请输入每个人的密码: ");
P=CreatList(n);
DeleList(n,P,m);
}。