约瑟夫环问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告
1.问题描述
设有编号为1,2,…,n的n(n>0)个人围成一个圈,每个人持有一个密码m。
从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。
当任意给定n和m后,设计算法求n个人出圈的次序。
2.设计思想
首先,设计实现约瑟夫环问题的存储结构。
由于约瑟夫环问题本身具有循环性质,考虑采用循环链表,为了统一对表中任意结点的操作,循环链表不带头结点。
将循环链表的结点定义为如下结构类型:
struct Node
{
int data;
Node *next;
};
其次,建立一个不带头结点的循环链表并由头指针first指示。
最后,设计约瑟夫环问题的算法。
3. 基本要求
●建立模型,确定存储结构。
●对任意n个人,密码为m,实现约瑟夫环问题。
●出圈的顺序可以依次输出,也可以用一个数组存储。
4.算法设计
1.系统里面自己定义了一个fun1函数,用来执行创建循环列表的功能。
YUE * fun1(int n)
{ YUE *head,*p1,*p2;
int i;
for(i=1;i<=n;i++)
{ p1=(YUE *)malloc(S());
if(i==1) head=p1;
else p2->next=p1;
p1->n=i;
p2=p1;
}
p1->next=head;
return head;
}
2.系统里面另外有定义了一个fun2的函数,用来执行满足条件出队列的功能。
int fun2(YUE *p)
{ YUE *p2;
int n;
p2=p->next;
n=p2->n;
p->next=p2->next;
free(p2);
return n;
}
3.在程序的开端,首先定义了一个链表结构。
typedef struct yuesefu
{ int n;
struct yuesefu *next;
} YUE;
4.在程序的中间部分,是程序的主函数,用来判断条件的满足与否。
YUE * fun1(int n);
int fun2(YUE *p);
int main()
{ int m,i,n,j,s;
YUE *p,*p2;
printf("n=");
scanf("%d",&n);
printf("m=");
scanf("%d",&m);
printf("i=");
scanf("%d",&i);
p=fun1(n);
for(j=1;j<i;p=p->next,j++);
j=1;p2=p;
while((p->next)!=p)
{ p=p->next;
if(++j==m)
{ j=1;p=p->next;
s=fun2(p2);
printf("%d ",s);
}
p2=p;
}
printf("%d\n",p->n);
system("pause");
}
5. 运行、测试与分析
先输入在队列中总人数n
再输入密钥m值
最后输入从第i个人开始报数
4.思考题
(1)采用顺序存储结构如何实现约瑟夫环问题?
创建一个具有n个元素的顺序表对象list。
从第s个元素开始,依次计数,每数到d,就将对应元素删除。
重复计数并删除元素,直到剩下一个元素。
如果每个人持有的密码不同,应如何实现约瑟夫环问题?
把每个人的密码定义出来,如果报数与其密码相等,出列。
附录:(代码)
#include <stdlib.h>
#include <stdio.h>
#define S() sizeof(struct yuesefu)
typedef struct yuesefu
{ int n;
struct yuesefu *next;
} YUE; /*定义链表*/ YUE * fun1(int n);
int fun2(YUE *p);
int main()
{ int m,i,n,j,s;
YUE *p,*p2;
printf("n=");
scanf("%d",&n);
printf("m=");
scanf("%d",&m);
printf("i=");
scanf("%d",&i);
p=fun1(n);
for(j=1;j<i;p=p->next,j++);
j=1;p2=p;
while((p->next)!=p)
{ p=p->next;
if(++j==m)
{ j=1;p=p->next;
s=fun2(p2);
printf("%d ",s);
}
p2=p;
}
printf("%d\n",p->n);
system("pause");
}
YUE * fun1(int n)
{ YUE *head,*p1,*p2;
int i;
for(i=1;i<=n;i++)
{ p1=(YUE *)malloc(S());
if(i==1) head=p1;
else p2->next=p1;
p1->n=i;
p2=p1;
}
p1->next=head;
return head;
} /*创建循环链表*/ int fun2(YUE *p)
{ YUE *p2;
int n;
p2=p->next;
n=p2->n;
p->next=p2->next;
free(p2);
return n;
} /*出队列函数*/。