约瑟夫环问题课程设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构
课程设计报告设计课题:约瑟夫问题
院系:计算机科学与技术学院
专业班级:计算机网络技术1102班学生姓名:张利
学号: 1 1 0 8 0 4 0 2 1 1 指导教师:王昱哲
目录
1.需求分析 (3)
1.1问题描述 (3)
1.2功能分析 (4)
2.概要设计 (5)
3.详细设计 (6)
4.调试与操作说明........... 1错误!未定义书签。总结. (16)
一.需求分析
1.1问题描述
约瑟夫环问题描述的是:设编号为1,2,…,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一正整数密码。开始时选择一个正整数作为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m时停止报数,报m的人出圈,将他的密码作为新的m值,从他在顺时针方向上的下一个人起重新从1报数。如此下去,直到所有人都出圈为止。令n最大值为100。要求设计一个程序模拟此过程,求出出圈的编号序列。如下图分析:
1.2功能分析
约瑟夫环问题是一个古老的数学问题,本次课题要求用程序语言的方式解决数学问题。此问题仅使用单循环链表就可以解决此问题。而改进的约瑟夫问题通过运用双向循环链表,同样也能方便地解决。
在建立双向循环链表时,因为约瑟夫环的大小由输入决定。为方便操作,我们将每个结点的数据域的值定为生成结点时的顺序号和每个人持有的密码。进行操作时,用一个指针current 指向当前的结点,指针front 始终指向头结点。然后建立双向循环链表,因为每个人的密码是通过rand()函数随机生成的,所以指定第一个人的顺序号,找到结点,不断地从链表中删除链结点,直到链表剩下最后一个结点,通过一系列的循环就可以解决改进约瑟夫环问题。
图2 约瑟夫环原理演示图
二、概要设计
1、循环链表抽象数据类型定义
typedef struct LNode//定义单循环链表中节点的结构
{
int num;//编号
int pwd;//password
struct LNode *next;//指向下一结点的指针}LNode;
2、本程序包含一下几个模块
(1)构造结点模块
LNode *createNode(int m_num,int m_pwd)
{
LNode *p;
p=(LNode *)malloc(sizeof(LNode));//生成一个结点
p->num=m_num;//把实参赋给相应的数据域
p->pwd=m_pwd;
p->next=NULL;//指针域为空
return p;
}
(2)创建链表模块
void createList(LNode *ppHead,int n)
(3)出队处理模块
void jose(LNode *ppHead,int m_pwd)
(4)约瑟夫环说明输出模块
void instruction()
(5)菜单模块
void menu()
(6)主函数模块
int main()
函数的调用关系图如下:
三、详细设计
1.主函数
图4 主函数数据流程图
根据流程图,主函数程序如下:
int main()
{
int n,m,x;
LNode *ppHead=NULL;
menu();
for(;;){
printf("\n请选择要执行的操作:");
scanf("%d",&x);
system("cls");
switch(x){
case 1:
printf("************************************************************ ****\n");
printf("约瑟夫环:\n");
printf(" 编号为1,2,3,4…,n的n个人按顺时针方向围坐一圈,每人持有一个密\n");
printf("码(正整数).一开始任选一个正整数作为报数的上限值m,从第一个人开始\n");
printf("按顺时针方向自1开始顺序报数,报到m时停止.报m的人出列,将他的密码\n");
printf("m作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,\n");
printf("直到所有人全部出列为止.编程打印出列顺序.\n");
printf("************************************************************ ****\n");
main();
break;
case 2:
printf("\n请输入总人数n:");
scanf("%d",&n);
printf("请输入开始上限数m:");
scanf("%d",&m);
createList(&ppHead,n);
printf("\n");
printf("出队顺序:\n");
jose(ppHead,m);
printf("\n约瑟夫环游戏结束!\n");
main();
break;
case 0:
exit(0);
default:
system("cls");
printf("\n您选择的操作有误,请重新选择...\n\n\n");
main();
}
}
return 0;
}
2.链表的创建