约瑟夫问题求解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
约瑟夫问题求解
一、问题描述。
1、实验题目
约瑟夫(Joseph)问题的一种描述是:编号为1,2,..., n 的n 个人按顺时针方向围坐一圈, 每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值,再从下个人开始新一轮报数,如此反复,直到剩下最后一人则为获胜者。试设计一个程序求出出列顺序。
2、实验要求
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
3、测试数据
n=7,7 个人的密码依次为:3,1,7,2,4,8,4 。m的初值为20,则正确的出列顺序应为6,1,4,7,2,3,5。
4、输入输出
输入数据:建立输入处理输入数据,输入n输入以及每个人的密码;m的初值。输出形式:建立一个输出函数,输出正确的序列。
二、需求分析
1、本程序实现求解约瑟夫问题,
2、程序运行后,要求用户指定初始报数上限值,然后读取个人密码。
输入数据:建立输入处理输入数据,输入m的初值,n,输入每个人的密码,建立单循环链表。
输出形式:建立一个输出函数,将正确的序列输出。
三、概要设计
定义的抽象数据类型:
栈的抽象数据类型定义:
ADT Stack{
数据对象:D={ai|ai∈ElemSet,i=1,2,...,n, n≥0,ElemSet为元素集合}
数据关系:R={
基本操作:
InitStack(&S); //构造空栈
DestroyStack(&S); //销毁栈
ClearStack(&S); //将栈置空
StackEmpty(S); //检查栈是否为空
StackLength(S); //返回栈中元素个数
GetTop(S,&e); //返回栈顶元素赋予e
Push(S,e); //插入e为新的栈顶元素
Pop(S,&e); //删除栈顶元素并赋予e StackTravers(S); //依次输出栈中元素。
}
四、详细设计
定义了以下结构体:
typedef struct LNode
{
int data;
struct LNode *next;
}LNode;
建立链表:
head=new LNode;
p=head;
for(i=1;i q=new LNode; p->next=q; p=q; } tail=q; tail->next=head; p=head; 主函数如下: void main( ) { int i,j,m,n,usless;LNode *head,*tail,*p,*q; printf("\nPlease input n:"); scanf("%d",&n); printf("\nPlease input m:"); scanf("%d",&m); head=new LNode; p=head; for(i=1;i { q=new LNode; p->next=q; p=q; } tail=q; tail->next=head; p=head; for(i=1;i<=n;i++) { p->data=i; /*printf("\nPlease enter No.%d's data:",i); scanf("%d",&p->data);*/ p=p->next; } printf("\nResult is as follow:\n"); p=tail; for(i=1;i<=n;i++) { for(j=1;j p=p->next; q=p->next; printf("%d ",q->data); p->next=q->next; j=1; } scanf("%d",&usless); } 五调试分析 出现的问题: 刚开始调试时,输出出现问题,最后一步DOS窗口消失,后在助教帮助下找出错误,解决了问题。 六、使用说明 输入数据:m=20,n=7,7 个人的密码依次为:3,1,7,2,4,8,4 输出数据:6,1,4,7,2,3,5。 七、调试结果 输入: m=20,n=7, 3,1,7,2,4,8,4 输出:6,1,4,7,2,3,5。 八:附录 约瑟夫chen.cpp