约瑟夫问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一问题描述
1 题目内容:约瑟夫(Joseph)问题的一种描述是:编号为1,2,..., n的n 个人按顺时针方向围坐一圈, 每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值。试设计一个程序求出出列顺序。
2 基本要求:利用单项循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
3 测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4(正确的出列顺序应为6,1,4,7,2,3,5)。
二需求分析
程序运行后,首先要求用户指定初始报数上限值,然后读取个人的密码。输入数据:建立输入处理输入数据,输入m的初值,n ,输入每个人的密码,建立单循环链表。输出形式:建立一个输出函数,将正确的输出序列
三概要设计
利用单项循环链表存储结构模拟此过程
1 循环链表的抽象数据类型
循环链表是单链表的一种变化形式,把单链表的最后一个节点的next指针指向第一个节点,整个链表就形成了一个环。
2 循环链表的基本操作(仅列出用在本程序的)
creat(n)
操作结果:构造一个长度为n的无头节点的循环链表,并返回指向最后一个节点的指针
find(m,s)
初始条件:循环链表存在
操作结果:找到当前元素(即s)后面第m个元素
print(&m,&n,&s)
初始条件:循环链表存在
操作结果:从s中删除约舍夫问题中下一个被删除的元素,并将此元素显示在屏幕上
3 本程序包括4个模块:
主程序模块;
创建循环链表模块;
找节点模块;
删节点模块;
各模块调用关系如下图所示:
4 约舍夫问题的伪码算法
void main( )
{
输入参与的人数;
输入第一个密码;
创建无头节点的循环链表;
输出第一个出列元素;
输出剩余出列元素;
}
四详细设计
1 实现概要设计的数据类型
typedef struct LNode
{int data;int num;struct LNode *next;}LNode,*linklist; //无头节点的循环链表的节点类型
2 每个子函数的算法
linklist creat(int n)
{/*构造一个长度为n的无头节点的循环链表,并返回指向最后一个节
点的指针*/
linklist head,s; //head为头节点标记s为链表中节点
int i;
s=head=(linklist)malloc(sizeof(LNode)); //创建头节点
for(i=1;i {s->data=i; printf("num%d: ",i); scanf("%d",&(s->num));/*输入第i个人的密码*/ while(s->num<=0) {/*如果输入的s->num小于等于0,要求重新输入*/ printf("请重新输入\nnum%d: ",i); scanf("%d",&s->num); } s->next=(linklist)malloc(sizeof(LNode)); //开辟下一个节点s=s->next; } s->data=i; printf("num%d: ",i); scanf("%d",&(s->num)); s->next=head; return(s); } linklist find(int m,linklist s) //找到当前元素后面第m个元素{ int i; for(i=0;i s=s->next; return(s); //返回找到元素的指针 } void print(into &mint &n,linklist &s) { linklist p; s=find(m,s); //找到待删除的元素 printf("%d ",s->next->data);/*输出找到的元素*/ m=s->next->num;/*将此元素从链表中删除,并释放此节点*/ p=s->next; s->next=s->next->next; free(p); --n; //约舍夫环中节点数少一 } 3 主程序算法 void main( ) {/*解决约舍夫问题的主函数*/ int n,m; //n为约舍夫环内初始人数m为初始密码 printf("type in n :"); scanf("%d",&n);/*输入n*/ while(n<=0) {/*如果输入的n小于等于0,要求重新输入*/ printf("please type n in again \ntype in n :"); scanf("%d",&n); } printf("type in m :"); scanf("%d",&m);/*输入m*/ while(m<0) {/*如果输入的m小于0,要求重新输入*/ printf("please type m in again \ntype in m :"); scanf("%d",&m); } linklist s; s=creat(n);/*创建无头节点的循环链表,返回指向最后一个元素的指针*/ printf("the sequence is "); print(m,n,s);//输出第一个出列的元素