数据结构实验报告约瑟夫环Word格式.docx
《数据结构实验报告约瑟夫环Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告约瑟夫环Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
![数据结构实验报告约瑟夫环Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/24/3b6ffd38-bb14-4be1-94fa-c0adbd24a714/3b6ffd38-bb14-4be1-94fa-c0adbd24a7141.gif)
杨静
实验室名称地点
21B276
哈尔滨工程大学
实验报告一
实验课名称:
实验名称:
班级
学号
姓名
时间2016.04.05
一、问题描述
设有编号为1,2,…,n的n(n>0)个人围成一个圈,每个人持有一个密码m。
从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。
当任意给定n和m后,设计算法求n个人出圈的次序。
二、数据结构设计
每个人按报数顺序有唯一的前驱与后继关系,并且报数顺序循环,所以采用单向循环链表模拟,链表节点存储序号number和m,存储结构定义如下:
typedefstructList{
intnumber;
//序号
intm;
//密码m
structList*next;
//指向下一个人的指针
}List;
为了方便查询及删除的定位,表按序号有序存储。
三、算法设计
1.初始化,构建循环链表,依次存储序号1至n的人,链表指针L指向序号为1的人。
List*create_list_with_one_m(List*L,intn){
List*pre;
//previousnode
inti=1;
for(;
i<
=n;
i++){
List*cur=(List*)malloc(sizeof(List));
//currentnode
cur->
number=i;
next=NULL;
if(i==1){//只在第一次进入,initL,pre
L=cur;
pre=cur;
}else{//链接pre与cur,并向后移动pre
pre->
next=cur;
}
next=L;
returnL;
}
2.为了获取被删除节点的前一个节点,m=1时重新赋值m为1+循环链表的长度,所以需要一个函数获取循环链表的长度。
//返回循环链表L的长度
intlength_list(List*L){
inti=1;
List*p=L->
next;
while(p!
=L){
i++;
p=p->
returni;
3.模拟报数过程,L永远指向下一个第一个报数的人,删除L开始后第m个节点,用结点指针del返回删除结点。
List*delete_node(List**L,intm,List*del){
if(m==1){//为了获取被删除节点的前一个节点,m=1时重新赋值为1+length
intl=length_list(*L);
m=1+l;
List*pri=*L;
//priornode
intj=0;
while(j<
m-2){//移动m-2次,获取pri
pri=pri->
j++;
del=pri->
//deletenode
pri->
next=del->
*L=pri->
returndel;
4.输入构建好的链表L,人数n,密码m,每次调用delete_node函数删除一人,进行n次。
voidjoseph_with_one_m(List*L,intn,intm){
while(i<
=n){//每次del一个node
List*del;
del=delete_node(&
L,m,del);
printf("
第%d个出圈的序号是%d\n"
i,del->
number);
free(del);
5.如果密码m不同,则删除节点后,以删除节点的密码m作为新的m。
voidjoseph_with_diff_m(List*L,intn){
intm=L->
m;
List*del=delete_node(&
m=del->
6.在主函数中获取人数和密码m,构建链表,调用joseph函数。
intmain(){
intn,m;
请输入人数n:
"
);
scanf("
%d"
&
n);
请输入所有人的m:
m);
List*L;
L=create_list_with_one_m(L,n);
joseph_with_one_m(L,n,m);
return0;
四、界面设计
程序需要获取人数n,密码m(相同的密码m和不同的密码m),输出出圈顺序。
所以以提示的形式获取n和m。
五、运行测试与分析
(1)运行程序,显示输入提示,如图所示。
(2)根据提示,输入人数,并输入密码,即可输出结果。
(3)需要不同密码的程序可根据提示输入不同密码,即可输出结果。
六、实验收获与思考
1.掌握了循环链表的初始化,删除,求长等常用方法的使用,巩固了相关数据结构。
2.在实验中熟悉了C语言对数据结构的描述,发现了过去的薄弱之处,重新进行学习。
3.体会到了正确的数据结构对程序的重要性。
七、附录
1.相同密码
#include<
stdio.h>
stdlib.h>
/*
*构建循环链表,依次存储1-n,L指向1
*pre:
previousnode
*cur:
currentnode
*/
/*
*删除L开始后第m个节点,用del返回
*L永远指向第一个报数的人
*pri:
priornode
*del:
deletenode
*/
i,del->
2.不同密码
List*create_list_with_diff_m(List*L,intn){
请输入第%d人的m:
i);
(cur->
m));
L=create_list_with_diff_m(L,n);
joseph_with_diff_m(L,n);
教师评分:
教师签字: