约瑟夫问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);//输出第一个出列的元素

相关文档
最新文档