约瑟夫环.docx
《约瑟夫环.docx》由会员分享,可在线阅读,更多相关《约瑟夫环.docx(12页珍藏版)》请在冰豆网上搜索。
约瑟夫环
数据结构
课程设计报告
设计题目:
约瑟夫环
专业网络工程
学生1高大力
指导教师路莹
起止时间2012.6.18-6.22
大连工业大学
课程设计任务书
课程设计名称
数据结构课程设计
专业
网络工程
学生姓名
高大力
班级
网络102
学号
1005040204
题目名称
约瑟夫环
起止日期
2012
年
6
月
18
日起至
2012
年
6
月
22
日止
课设内容和要求:
编号为1,2…n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
要求:
1、利用单循环链表作为存储结构模拟此过程;
2、键盘输入总人数、初始报数上限值m及各人密码;
3、按照出列顺序输出各人的编号。
参考资料:
《算法与数据结构》
《C语言程序设计》
教研室审核意见:
教研室主任签字:
指导教师(签名)
年
月
日
学生(签名)
年
月
日
目录
1问题分析3
1.1问题重述3
1.2问题分析3
2程序设计4
2.1总体设计4
2.1.1数据结构设计4
2.1.2函数设计4
2.2函数调用关系5
2.3主要函数流程图6
3调试分析8
4测试及运行结果9
参考文献10
附录11
1问题分析
1.1问题重述
题目要求的约瑟夫环操作:
编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
设计一个程序来求出出列顺序。
1.2问题分析
本程序主要是以建立单循环链表的形式,建立起一个约瑟夫环,然后根据之前创立的结点,输入结点里的一些数据,如下
typedefstructNode
{
intIndex;在当前环中所处的位置,即编号
intPassword;在当前环中的所带的密码
structNode*next;
}JosephuNode;
程序有主函数开始,首先,提示输入创建约瑟夫环环数以及每个环上所带的密码。
然后,开始调用JosephuNode*Creat_Node函数,利用单循环链表建立起约瑟夫环,tail->next=head;就是将最后一个结点的后继指向头结点,函数结尾returnhead;将约瑟夫环的头指针返回,并将它赋值head,然后主函数继续调用Josephu函数,通过讲head和Password引入函数,以建立两个嵌套循环输出并实现题目所要求的功能。
2程序设计
2.1总体设计
2.1.1数据结构设计
使用单循环链表创建约瑟夫环:
#include
#include
typedefstructNode
{
intIndex;
intPassword;
structNode*next;
}JosephuNode;
2.1.2函数设计
表2.1函数列表
函数名称
函数原型
功能描述
main
voidmain()
主函数,程序入口
Creat_Node
JosephuNode*Creat_Node
创建约瑟夫环
Josephu
voidJosephu
输出约瑟夫环的结果
2.2函数调用关系
图2.2函数调用关系图
2.3主要函数流程图
(1)Creat_Node函数流程图如图2.3所示
inti,pass;
JosephuNode*head,*tail;
head=tail=(JosephuNode*)malloc(sizeof(JosephuNode));
for(i=1;itail->Index=i
printf("\t\t请输入第%d号所带密码:
",i)
scanf("%d",&pass)
tail->Password=pass
tail->next=(JosephuNode*)malloc(sizeof(JosephuNode))
tail=tail->next
tail->Index=i
printf("\t\t请输入第%d号所带密码:
",i)
scanf("%d",&pass)
tail->Password=pass;
tail->next=head;
returnhead
图2.3JosephuNode*Creat_Node流程图
(2)Josephu函数流程图
inti,j
JosephuNode*tail
for(i=1;tail!
=head;++i)
for(j=1;jtail=head
head=head->next
tail->next=head->next
printf("\n\t\t第%d个出局的人的编号是:
%d\t密码是:
%d",i,head->Index,head->Password
Password=head->Password
free(head)
head=tail->next
i=head->Password
j=head->Index
printf("\n\t\t第7个出局的人的编号是:
%d\t密码是:
%d\n",j,i)
free(head)
图2.4Josephu函数流程图
3调试分析
1、问题:
若输入相同的数字,可能导致程序无法正确的建立单循环链表
解决:
建立一个函数,使如果输入了相同的数字,则会ruturnerror,使程序终止。
2、问题:
输入的数据为空时无法继续程序的运行。
解决:
经查阅书籍,更正错误,修正程序。
4测试及运行结果
5
图2.5约瑟夫环的运行结果
参考文献
[1]严蔚敏,吴伟民.数据结构(C语言版).北京:
清华大学出版社,2007
[2]谭浩强,C语言程序设计教程.北京:
清华大学出版社,2005
[3]徐孝凯,数据结构课程实验.北京:
清华大学出版社,2006
[4]秦锋,袁志祥数据结构(C语言版)例题详解与课程设计指导.北京:
中国科学技术大学出版社,2007
[5]秦锋,数据结构(C语言版).北京:
中国科学技术大学出版社,2005
附录
源程序清单:
#include
#include
typedefstructNode
{
intIndex;
intPassword;
structNode*next;
}JosephuNode;
///////////////////////////////////////////////使用单循环链表创建约瑟夫环
JosephuNode*Creat_Node(intnumbers)
{
inti,pass;
JosephuNode*head,*tail;
head=tail=(JosephuNode*)malloc(sizeof(JosephuNode));//申请头结点
for(i=1;i{
tail->Index=i;
printf("\t\t请输入第%d号所带密码:
",i);//输入当前结点所带密码
scanf("%d",&pass);
tail->Password=pass;
tail->next=(JosephuNode*)malloc(sizeof(JosephuNode));//申请一个新结点
tail=tail->next;//指针指向下一个结点
}
tail->Index=i;
printf("\t\t请输入第%d号所带密码:
",i);
scanf("%d",&pass);
tail->Password=pass;
tail->next=head;//将尾结点指针指向表头
returnhead;
}//Creat_Node
/////////////////////////////////////////////////约瑟夫环
voidJosephu(JosephuNode*head,intPassword)
{
inti,j;
JosephuNode*tail;
for(i=1;tail!
=head;++i)
{
for(j=1;j{
tail=head;
head=head->next;
}
tail->next=head->next;
printf("\n\t\t第%d个出局的人的编号是:
%d\t密码是:
%d",i,head->Index,head->Password);
Password=head->Password;
free(head);
head=tail->next;
}
i=head->Password;
j=head->Index;
printf("\n\t\t第7个出局的人的编号是:
%d\t密码是:
%d\n",j,i);
free(head);
}//Josephu
/////////////////////////////////////
voidmain()
{
intnumbers,Password;
charstop;
JosephuNode*head;
printf("\t\t-----------------约瑟夫环问题-----------------\n");
printf("\t\t例如:
输入约瑟夫问题的人数和起始密码:
7,20\n");
printf("\t\t---------------------------------------------------\n");
do
{
printf("\t\t开始...\n\t\t输入约瑟夫环问题的人数和起始密码:
");
scanf("%d,%d",&numbers,&Password);
head=Creat_Node(numbers);
printf("\t\t---------------\n");
printf("\t\t输出结果如下\n");
Josephu(head,Password);
printf("\t\t-----------------------------------------------\n");
printf("\t\t是否继续进行?
是Y(y),否N(n)\t");
getchar();
scanf("%c",&stop);
getchar();
printf("\t\t-----------------------------------------------\n");
}while(stop=='y'||stop=='Y');
}
课程设计总结:
此程序目前的缺点在于,结点密码数据类型定义的存储类型是int型,不能超过-2147483648~2147483648,一旦超过则程序输出结果有误,另一个缺点就是程序运行当中,一旦中途输入出现错误,则无法返回,必须将当前操作结束等到下个主函数的循环开始,或者直接退出重新运行此程序。
优点则在于程序运行速度较快,不会出现输出结果有误的问题
经过这次集中上机的实验,从开始选题到自己上手还是编写程序的过程中,我学会了很多的东西,以前对C语言的知识和算法总是模棱两可的,经过这次练习,在某些方面上还是经过了加强的训练。
此次,实验,从开始构建循环链表然后实现约瑟夫环功能的过程中,中途也遇见一些问题,但都逐一克服,相信在这次的实验中提升了较大的自身动手实践能力。
学好数据结构!
指导教师评语:
指导教师(签字):
年月日
课程设计成绩