数据结构实验报告约瑟夫环.docx
- 文档编号:7802089
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:13
- 大小:28.40KB
数据结构实验报告约瑟夫环.docx
《数据结构实验报告约瑟夫环.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告约瑟夫环.docx(13页珍藏版)》请在冰豆网上搜索。
数据结构实验报告约瑟夫环
数据结构与程序设计实验
实验报告
课程名称
数据结构与程序设计实验
课程编号
0906550
实验项目名称
约瑟夫环
学号
年级
2014
姓名
专业
计算机科学与技术
学生所在学院
计算机学院
指导教师
杨静
实验室名称地点
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;
cur->next=NULL;
if(i==1){//只在第一次进入,initL,pre
L=cur;
pre=cur;
}else{//链接pre与cur,并向后移动pre
pre->next=cur;
pre=cur;
}
}
pre->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->next;
}
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 pri=pri->next; j++; } del=pri->next;//deletenode pri->next=del->next; *L=pri->next; returndel; } 4.输入构建好的链表L,人数n,密码m,每次调用delete_node函数删除一人,进行n次。 voidjoseph_with_one_m(List*L,intn,intm){ inti=1; while(i<=n){//每次del一个node List*del; del=delete_node(&L,m,del); printf("第%d个出圈的序号是%d\n",i,del->number); free(del); i++; } } 5.如果密码m不同,则删除节点后,以删除节点的密码m作为新的m。 voidjoseph_with_diff_m(List*L,intn){ inti=1; intm=L->m; while(i<=n){//每次del一个node List*del=delete_node(&L,m,del); printf("第%d个出圈的序号是%d\n",i,del->number); m=del->m; free(del); i++; } } 6.在主函数中获取人数和密码m,构建链表,调用joseph函数。 intmain(){ intn,m; printf("请输入人数n: "); scanf("%d",&n); printf("请输入所有人的m: "); scanf("%d",&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 #include typedefstructList{ intnumber; intm; structList*next; }List; /* *构建循环链表,依次存储1-n,L指向1 *pre: previousnode *cur: currentnode */ List*create_list_with_one_m(List*L,intn){ List*pre; inti=1; for(;i<=n;i++){ List*cur=(List*)malloc(sizeof(List)); cur->number=i; cur->next=NULL; if(i==1){//只在第一次进入,initL,pre L=cur; pre=cur; }else{//链接pre与cur,并向后移动pre pre->next=cur; pre=cur; } } pre->next=L; returnL; } //返回循环链表L的长度 intlength_list(List*L){ inti=1; List*p=L->next; while(p! =L){ i++; p=p->next; } returni; } /* *删除L开始后第m个节点,用del返回 *L永远指向第一个报数的人 *pri: priornode *del: deletenode */ 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; intj=0; while(j pri=pri->next; j++; } del=pri->next; pri->next=del->next; *L=pri->next; returndel; } voidjoseph_with_one_m(List*L,intn,intm){ inti=1; while(i<=n){//每次del一个node List*del; del=delete_node(&L,m,del); printf("第%d个出圈的序号是%d\n",i,del->number); free(del); i++; } } intmain(){ intn,m; printf("请输入人数n: "); scanf("%d",&n); printf("请输入所有人的m: "); scanf("%d",&m); List*L; L=create_list_with_one_m(L,n); joseph_with_one_m(L,n,m); return0; } 2.不同密码 #include #include typedefstructList{ intnumber; intm; structList*next; }List; /* *构建循环链表,依次存储1-n,L指向1 *pre: previousnode *cur: currentnode */ List*create_list_with_diff_m(List*L,intn){ List*pre; inti=1; for(;i<=n;i++){ List*cur=(List*)malloc(sizeof(List)); cur->number=i; printf("请输入第%d人的m: ",i); scanf("%d",&(cur->m)); cur->next=NULL; if(i==1){//只在第一次进入,initL,pre L=cur; pre=cur; }else{//链接pre与cur,并向后移动pre pre->next=cur; pre=cur; } } pre->next=L; returnL; } //返回循环链表L的长度 intlength_list(List*L){ inti=1; List*p=L->next; while(p! =L){ i++; p=p->next; } returni; } /* *删除L开始后第m个节点,用del返回 *L永远指向第一个报数的人 *pri: priornode *del: deletenode */ 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; intj=0; while(j pri=pri->next; j++; } del=pri->next; pri->next=del->next; *L=pri->next; returndel; } voidjoseph_with_diff_m(List*L,intn){ inti=1; intm=L->m; while(i<=n){//每次del一个node List*del=delete_node(&L,m,del); printf("第%d个出圈的序号是%d\n",i,del->number); m=del->m; free(del); i++; } } intmain(){ intn,m; printf("请输入人数n: "); scanf("%d",&n); List*L; L=create_list_with_diff_m(L,n); joseph_with_diff_m(L,n); return0; } 教师评分: 教师签字:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 约瑟夫