数据结构课程设计约瑟夫环.docx
- 文档编号:8234784
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:9
- 大小:201.42KB
数据结构课程设计约瑟夫环.docx
《数据结构课程设计约瑟夫环.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计约瑟夫环.docx(9页珍藏版)》请在冰豆网上搜索。
数据结构课程设计约瑟夫环
课程设计报告书
课程名称:
数据结构
题目:
约瑟夫环
学生姓名:
专业:
计算机科学与技术(网络方向)
班别:
计科本113班
学号:
**********
指导老师:
日期:
2013年1月4日
摘要
约瑟夫环是一个比较热门的问题,它的问题描述是:
编号为1,2…n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止。
利用单循环链表作为存储结构模拟此过程,键盘输入总人数、初始报数上限值m及各人密码,按照出列顺序输出各人的编号,通过输出函数确定每一个报数人的位置并不断地从链表中删除链结点直到链表为空,最终得到出列序列。
关键词约瑟夫环数据结构单向循环链表删除结点
一、问题描述
编号为1,2…n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
二、基本要求
1、利用单循环链表作为存储结构模拟此过程;
2、键盘输入总人数、初始报数上限值m及各人密码;
3、按照出列顺序输出各人的编号。
三、工具/准备工作
翻阅《c语言程序设计》了解有关结构体有关的知识,翻阅《数据结构与算法》了解单循环链表的建立,阅读有关的资材,在自己的win7系统上安装了Vc++软件。
四、分析与实现
4.1分析
1.首先定义一个结构体数据类型作为链表结点类型。
该结构体中包含两个整型变量和一个指向该结构体变量的指针。
一个整型变量中存放的是每个人的编号,另一个整型变量存放的是每个人的密码,指针指向链表中的下一个结点。
2.根据设计内容要求,建立一个单向循环链表,其结点是上述问题描述中的人。
每个人有一个编号,以此编号来区分各个人,设计一个建立单向循环链表的函数。
该链表建立时,是建立一个不带头结点的循环链表,因此在建立过程中,链表的头指针会发生改变,故在该函数中,头指针作为实参传入CreateList()函数时,要以引用的方式传入。
这样才能使在主函数中的链表头指针也发生相应的变化。
而在设计建立过程的时候,由于希望保持与输入顺序相同,每个结点的插入是在链表尾部进行,依次插入,直至结束。
3、设计单链表以及存放密码的函数CreateList()
该函数有两个参数,即循环链表的头指针L,报数人数亦即链表长度n。
这个过程共被循环n次,也即所有结点都被删除,即所有人都出列,此时,模拟过程完成,函数结束。
其中,删除结点的过程单独作为一个函数来实现。
通过此函数存放每个人的密码。
4、设计一个出列的函数putout()
由于该单向循环链表没有头结点,因此,每种不同的情况需要分别考虑。
首先是当链表只剩下一个结点的时候,这时就直接令头指针L为空,即可删除该结点。
其次是当待删除结点是循环链表的第一个结点,即是头指针所指向的结点时,要改变L的值,使其指向下一个结点,然后再删除该结点。
最后是一般情况,删除链表中间结点,此时可以直接删除。
由于该函数执行也会改变头指针L的值,因此指针L在传入的时候,需要传入该指针的引用。
5.设计main()调用CreateList()和putout()这两个子函数,实现设计的要求。
6、在即将删除的同时,输出每个结点的信息,即出列的人的编号。
4.2实现
typedefstructNode
{
intnum;
intcode;
structNode*next;
}LNode,*LinkList;
在这里我建立了一个结构体,用num存入各个人的编号,用code来存放各个人的密码。
LinkListCreateList(LinkListL,intn)
{
inti;
LinkListp,q;
L=(LNode*)malloc(sizeof(LNode));
L->next=NULL;
q=L;
for(i=1;i<=n;++i)
{
p=(LNode*)malloc(sizeof(LNode));
p->num=i;
printf("输入第%d个人的密码",i);
scanf("%d",&p->code);
p->next=NULL;
q->next=p;
q=p;
}
q->next=L->next;
p=L;
L=L->next;
free(p);
returnq;
}
在这里我建立了一个单循环链表,申请空间并存放每个人的密码,定义了三个指针变量L,p,q,使用scanf从键盘输入各个人的密码。
voidputout(LinkListq,intm)
{
inti;
LinkListp,x;
printf("\n");
printf("出列人的编号顺序如下:
\n");
do
{
i=1;
while(i!
=m)
{
q=q->next;
i++;
}
p=q->next;
q->next=p->next;
printf("编号为%d的人出列\t他的密码为%d作为新m",p->num,p->code);
printf("\n");
m=p->code;
free(p);
}
while(q->next!
=q);
printf("编号为%d的人出列,所有人出列完毕",q->num);
free(q);
printf("\n\n约瑟夫环结束\n");
printf("按任意键结束\n\n");
printf("结束,谢谢!
");
}
在这里,我设计了一个函数,该函数的主要功能是把出列的人的密码作为新的m值,最终按出列的顺序输入出各个人的编号。
intmain(void)
{
intn,m;
LinkListp,q;
printf("约瑟夫问题现在设计程序实现功能如下");
printf("\n");
printf("请输入参与人总数n");
scanf("%d",&n);
printf("请输入报数的上限值m");
scanf("%d",&m);
q=CreateList(p,n);
putout(q,m);
return0;
}
在这里,我首先使用scanf报上上限值m,然后就调用Createlist(p,n)和putout(q,n)这两个子函数。
五、测试与结果
n=10,10个人的密码依次是9、8、11、4、6、5、3、2、15、21,运行结果如下图1所示
图1
n=9,9个人的密码依次是6、5、4、7、8、9、3、2、1,m=5,运行结果如下图2所示
图2
n=8,8个人的密码依次是4、5、3、2、1、7、8、6,m=6,运行结果如下图3所示
图3
n=7,7个的密依次是4、3、1、2、5、7、6,m=5,运行结果如下图4所示
图4
n=6,6个人的密码依次是5、4、2、3、1、6,m=3,运行结果如下图5
图5
通过五次的测试,都获得了成功,都符合题目的要求,正确的出列。
六、课程设计总结
通过本次的课程设计,我对数据结构有关的知识有了进一步的了解,刚刚开始我并不知道如何去完成这次的课程设计,但通过我去网上查询有关的资料,我最终知道该从哪里下手去写这篇课程设计。
通过本次的课程设计,我知道了自己身上的不足和自己知识的欠缺。
本次课程设计,我不断的调试代码,花了较多的时间,最终成功的把代码调试好,心中充满着喜愉,通过本课程设计,我增加了许多的知识,对单循环链表的使用,我比以前有了更进一步的了解。
通过本次的课程设计,发现自己在数据结构方面的了解不足,在调试代码中,发现有较多的错误,这些错误的产生都是因为我对知识的认识不够深入而产生的。
对于子函数的使用我还不够清楚,导致产生了很多的错误,通过本次的课程设计,我对子函数的使用有了一定的了解。
通知过本次的课程设计暴露出我对c语言的掌握还不是很好,需要我自己去加强学习。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 约瑟夫