工作报告之约瑟夫环实验报告总结文档格式.docx
- 文档编号:22010550
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:11
- 大小:22.27KB
工作报告之约瑟夫环实验报告总结文档格式.docx
《工作报告之约瑟夫环实验报告总结文档格式.docx》由会员分享,可在线阅读,更多相关《工作报告之约瑟夫环实验报告总结文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
上机地点:
综合楼311
四、实验过程与分析
(1)主要的函数或操作内部的主要算法,分析这个算法的时、空复杂度,并说明设计的巧班级:
学号:
姓名:
组号:
实验成绩:
批阅教师签字:
实验日期:
实验时间:
妙之处。
本实验中主要的函数包括创建链表、显示链表内容和出列过程四个部分。
主要函数的代
码如下:
创建链表:
typedefintdatatype;
typedefstructnode//链表的定义
{
datatypedata;
intpassword;
structnode*next;
}listnode,*clinklist;
voidcreatlist_cl(clinklist*l,intn)//创建一个链表
inti,pin;
clinklistp,q;
(*l)=(clinklist)malloc(sizeof(listnode));
if((*l)==null)
printf(error\n);
else
(*l)-next=null;
q=*l;
for(i=0;
in;
i++)
{p=(clinklist)malloc(sizeof(listnode));
if(p==null)printf(error\n);
printf(请输入第%d个人的密码:
i+1);
scanf(%d,pin);
p-data=i+1;
p-password=pin;
q-next=null;
q-next=p;
q=p;
}
q-next=(*l)-next;
//指向l结点,形成
创建这个链表的时间复杂度为o(n),空间复杂度为o(n2)显示链表中的信息内容:
voiddisplay(clinklist*l,intn)
inti;
clinklistp;
p=(*l)-next;
printf(\n显示链表内容\n);
printf(编号:
%2d密码:
%d\n,p-data,p-password);
p=p-next;
该算法的时间复杂度为o(n),空间复杂度为o(n2)。
删除结点,完成出列功能:
voiddelete_l(clinklist*l,intn,intm)
inti=0,j;
q=(*l);
p=(*l)-next;
printf(\n删除的顺序:
\n);
while(in)
for(j=0;
jm-1;
j++)
{q=p;
%d密码:
m=p-password;
q-next=p-next;
free(p);
p=q-next;
n--;
}该算法的时间复杂度为o(n2),空间复杂度为o(n2)。
该设计的巧妙之处在于并不需要额外的空间来存储数据,因而空间复杂度较低,而且线性表的链式存储结构可以用物理位置上的邻接关系来表示结点间的逻辑关系,这样使读者在阅读代码的过程中可以更加方便和便于理解。
它可以随机存取表中的任一结点,还可以免插入和删除操作带来的大量的结点的移动,能给结点动态分配内存,这样就不存在存储空间不足的情况,而且循环链表还可以方便的从链表的最后一个结点遍历到链表的第一个结点。
使
操作更加方便。
(2)你在调试过程中发现了怎样的问题?
又做了怎样的改进
1)在最开始的调试阶段,我发现链表插入结束之后,不能按照正常情况下输出链表的
内容,只能正常显示第一个人的数据,在显示第二个人的信息是数据为乱码。
之后我发现,
在插入链表的过程中,我是在执行循环插入数据的循环中将结点的指针指向了第一个结点,
因而,在进行链表显示的过程中,第二个结点的内容不是正常的数据。
之后我将
这条指令放到了整个插入循环的外部,这样表示在插入所有数据之后,
最后一个结点的指针指向了第一个结点,形成了一个循环队列,此时链表的数据显示正确。
2)再次调试时,我发现人员出列时,只有第一个人出列正常,在第二个人出列时程序
自动终止,不能正常显示之后出列的人的信息,并且程序自动终止运行,经过检查我发现在
经过一次删除后,没有将指针指向下一个结点,因而出现问题。
经过更改,程序运行正常。
3)在实验的开始阶段,数据遍历总是出现问题,经过查找资料我发现了约瑟夫环头结
点的特殊性,因此我不再使用头结点,程序便恢复正常了。
(2)测试结果
五、实验结果总结回答以下问题:
(1)你的测试充分吗?
为什么?
你是怎样考虑的?
答:
我认为我的测试充分,因为我随机选用了很多组不同的数据进行测试,并且
每次测试的结果都是正确的答案,这样选取的数据具有很强的随机性,具有代表性,
因而我认为我的测试比较充分。
(2)你的存储结构的选取是不是很适合这个应用?
我认为我选取的线性链式存储结构适合这个应用,因为首先此题中描述的情
景中表示人们按照顺时针的方向进行排队,此时头尾相连,这与循环链表的结构十分
相似,使用循环链表的结构,这样可以很方便的从链表的最后一个结点访问到链表的
第一个结点,并且这样的存储方式是用物理位置上的邻接关系来表示结点间的逻辑关
系,根据这个特点,该种结构可以随机存取表中的任一结点,而且它也可以避免插入
和删除操作带来的大量结点的移动,并且可以随时分配空间和释放空间,这样可以减
少空间的使用量,并且可以做到灵活的扩充空间,这样的结构很适合这个应用。
(3)用一段简短的代码及说明论述你的应用中有关插入和删除元素是如何做的?
答:
插入元素:
首先定义了两个临时指针p和q来分别表示新插入结点的指针和第一个结点的指针,在每次插入之前应该动态的分配内存,输入要输入的信息,并且将各种数据存储到链表中相应的项里,将前一个结点的next赋值为空,再将前一个结点的指针指向下一个结点,此时完成一个元素的插入。
依次类推,运用循环来实现所
有人的数据的插入,关键代码如下:
p=(clinklist)malloc(sizeof(listnode));
if(p==null)printf(error\n);
printf(请输入第%d个人的密码:
q=p;
删除元素:
进行循环来实现每个元素出列的功能,首先每个人进行循环,一
次进行报数,在报到m-1之前都不进行删除元素这个动作,在m时,把此时结点中的
password中的数值赋给m然后运用q-next=p-next;
将结点删除,同时释放结点p,
将人数减1,以此类推完成所有的删除操作,直到所有的元素出列,关键代码如下:
while(in)
{for(j=0;
m=p-password;
free(p);
(4)在你的应用中是否用到了头结点?
你觉得使用头结点为你带来方便了吗?
在我的应用中我没有用到头结点。
在实验的一开始,我使用了头结点,但是
使用头结点给数据的遍历带来了困难,因此我便放弃使用头结点。
(5)源程序的大致的执行过程是怎样的?
首先用编译器编写一个.c的文件,然后编译生成.obj的文件,通过连接将目标
文件连接生成一个.exe文件,之后运行文件就可以执行了。
六、附录
(1)实验设想和建议这次实验提高了我对数据结构中关于循环链表和顺序表的理解,提高了我的编程
能力,学校以后最好可以增加实验课的课时,这样我们可以更大程度的提高自己的编
程能力。
另外我认为该实验不仅可以使用使用链表指针来实现,还可以使用数组来模
拟链表来实现约瑟夫环,用数组的下标来指向前一个和后一个元素,之后进行删除来
实现约瑟夫环。
(2)参考资料:
《数据结构(第二版)》闫玉宝编著清华大学出
版社
【篇二:
《数据结构与算法设计》实验报告
——实验一
学院:
自动化学院
班级:
06111001学号:
1120101525
姓名:
王冬
一、实验目的
1、熟悉vc环境,学习使用c语言利用链表的存储结构解决实际的问题。
2、在编程、上机调试的过程中,加深对线性链表这种数据结构的基本概念理解。
3、锻炼较强的思维和动手能力和更加了解编程思想和编程技巧。
二、实验内容
1、采用单向环表实现约瑟夫环。
请按以下要求编程实现:
①从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。
环表中的结点编号依次为1,2,?
?
,m。
②从键盘输入整数s(仁s=m)和n,从环表的第s个结点开始计数为1,当计数到第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点的下一个结点开始重新计数到n,这样,不断进行计数,不断进行输出,直到输出了这个环表的全部结点为止。
例如,m=10,s=3,n=4。
则输出序列为:
6,10,4,9,5,2,1,3,8,7。
三、程序设计
1、概要设计为了解决约瑟夫环的问题,我们可以建立单向环表来存储每个人的信息(该人的编号以及其下一个人的编号),及结点,人后通过查找每个结点,完成相应的操作来解决约瑟夫问题。
(1)抽象数据类型定义
adtjoh{
数据对象:
d={ai|ai?
elemset,i?
1,2,?
n,n?
0}数据关系:
r1={?
ai?
1,ai?
|ai?
d,i?
n}基本操作:
create(j,n)操作结果:
构造一个有n个结点的单向环表j。
show(j)初始条件:
单向环表j已存在。
操作结果:
按顺序在屏幕上输出j的数据元素。
calculate(j,s,n)
初始条件:
单向环表j已存在,s0,n0,s环表结点数。
操作结果:
返回约瑟夫环的计算结果。
}adtjoh
(2)宏定义
#definenull0
#defineok1
#defineerror-1
(3)主程序流程
(4)程序分为下述模块:
1)主函数模块——执行输入调用其他的功能函数
2)创建环表模块——创建单向环表
3)计算处理模块——计算出要出列的标号并输出4)显示模块——输出建立好的环表调用关系如下:
2、详细设计
(1)数据类型设计
typedefintelemtype;
//元素类型typedefstruct{elemtypedata;
structjoh*next;
}joh,*linklist,*p;
//结点类型,指针类型
(2)操作算法statuscreate(linklistj,intn){
//创建一个有n个结点的单向环表if(n=0)returnerror;
//n0错误j=(linklist)malloc(sizeof(j));
j-data=1;
j-next=j;
//建立第一个结点for(inti=n;
i1;
--i){p=(linklist)malloc(sizeof(j));
p-data=i;
【篇三:
约瑟夫环问题_实验报告】
年级12级学号12061633姓名徐超杰
一、实验目的本实验的目的是进一步理解线性表的逻辑结构和存储结构,进一步提高使用理
论知识指导解决实际问题的能力。
二、实验问题描述人从1
开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
三、实验步骤
1、实验问题分析
1由于当某个人退出圆圈后,报数的工作要从下一个人开始继续,剩下的人仍要是围成一个圆圈,可以使用循环表;
由于退出圆圈的工作对应着表中结点的
删除操作,对于这种删除操作频繁的情况,应该选用效率较高的链表结构;
为了
程序指针每一次都指向一个具体的代表一个人的结点而不需要进行判断,链表不
带表头结点。
所以,对于所有人围成的圆圈所对对应的数据结构采用一个不带头
结点的循环链表来描述。
设头指针为p,并根据具体情况移动可以采用数据类型定义:
typedefstructnode
intnumber;
}lnode,*linklist;
2为了记录退出的人的先后顺序,采用一个顺序表进行存储,程序结束后再
输入依次退出的人的编号顺序。
由于只记录各个结点的number值就可以,所以
定义一个整型一维数组。
如“intquite[n];
为一个根据实际问题定
义的一
个足够大的整数。
2、功能(函数)设计
根据上述分析,该算法可以由3个功能函数实现。
main()用做数据的输入和
函数的调用,init()做链表的初始化工作,使用josephus()做删除结点和保存
输出顺序的工作,outring()完成序列的输出工作。
1.建立单循环链表函数linklistinitringlist(intn);
2.产生josephus顺序函数voidjosephus(linklistl,intn,intk,intm,intquit[n])
3.输出顺序表voidprint(intn,intquit[n])
四、实验结果(程序)及分析
1.实验的的源代码:
//约瑟夫环问题.cpp:
definestheentrypointfortheconsoleapplication.
//
//#includestdafx.h
#includeiostream.h#definen34
typedefstructnode
intdata;
linklistinitringlist(intn)//尾插法建立单循环链表
lnode*l,*r,*s;
l=newlnode;
//不带头结点
r=l;
for(inti=1;
s=newlnode;
r-data=i;
r-next=s;
r=s;
r-data=n;
r-next=l;
//链表首尾相连l=r;
//l指向循环链表的尾结点returnl;
voidjosephus(linklistl,intn,intk,intm,intquit[n])
inti,j;
lnode*p,*q;
p=l;
for(intr=1;
rm;
r++)p=p-next;
{for(j=1;
j=k-1;
j++)p=p-next;
q=p-next;
p-next=q-next;
quit[i]=q-data;
deleteq;
voidprint(intn,intquit[n])
for(i=0;
i++)coutquit[i];
coutendl;
intmain(intargc,char*argv[])
linklistl;
intn;
intk;
intm;
cout请输入围坐一圈的人数n的值:
endl;
cinn;
l=initringlist(n);
intquit[n];
cout约定从编号为m的值开始数,请输入m的值:
cinm;
while(mn||m1)
cout输入错误,请重新输入:
endl;
cinm;
cout要求数到k的人出列,请输入k的值:
cink;
cout顺序为:
;
josephus(l,n,k,m,quit);
print(n,quit);
return0;
2.测试数据
a.当n的初始值为7,k的值为5,m的值为1时,正确的出列顺序为:
5、3、2、4、7、1、6,经程序运行测试,结果如下:
可知程序运行正确。
b.程序的容错性测试,当输入m的值不符合问题约定时,应有错误提示给用户,指导用户正确输入,并做出相应处理,保证程序运行。
测试如下:
3.测试中出现的问题
a.在此次编写中一个for循环出现的位置发生了错误,但程序仍可运行,可是这样运行出来的数据的顺序会发生错误,解决此类问题的方法是多运行几次,而且应该有这样一个概念运行出来和调试没有错误不一定代表没有了错误。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 工作报告 约瑟夫 实验 报告 总结