数据结构约瑟夫环实验报告

  1. 实验目的及要求

目的:能够熟练掌握线性表的基本操作在顺序和链式两种存储结构上的实现,进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力。

要求:1.建立数据模型,确定存储结构;

2.对任意人数、密码,都能实现约瑟夫环问题;

3.出圈顺序可以依次输出,也可以用一个数组输出。

  1. 实验步骤

1.实验问题分析

(1)由于当某个人退出圆圈后,报数的工作要从下一个人继续,剩下的人仍要围成一个圆圈,这个问题具有循环性质,考虑使用循环链表; 由于退出圆圈的这个指令对应着结点的删除操作,且这种删除操作使用频繁,考虑选择效率较高的链表结构;

循环链表的结点定义为如下结构类型:

创建一个长度为n的循环链表:

      

(2)由于退出圆圈的这个指令对应着结点的删除操作,于是定义了一个delete函数。在删除结点的时候考虑到几个特殊的情况,头尾结点。在删除第一个结点时,需要将head 指针下移,尾结点的next也需指向第二个结点;删除尾结点时,要将尾结点前的结点与第一个结点相连。当只剩下一个结点时,不需要删除,直接输出data的值。具体实现函数如下:

(3)主程序执行。主程序运行时,调用函数。

 

  1. 实验内容
  1. 从键盘输入整数n,通过create函数生成一个具有n个结点的循环链表。表中结点的编号依次为1,2,3,4,……

2.从键盘输入整数m(出圈数)和n(总人数)(1<=m<=n),从第1个结点开始计数为1,当计数到第m个结点时,输出该第m 结点对应的编号,将该结点从表中消除,并从输出结点的下一个结点开始计数器count重新计数到m,这样,不断重复进行计数,不断地输出,直到输出了这个链表的全部结点为止。

如,当n=8,m=3时,输出序列为:3,6,1,5,2,8,4,7。

3.代码的实现如下:

#include <iostream>

#include <stdlib.h>

#include <stdio.h>

using namespace std;


struct jd

{

int s;

jd*next;

};


jd*creat(int array[],int n)//循环链表

{

jd*p,*head,*pe;//创建指针

head=new jd;//创建空地址

head->next=NULL;//置空

pe=head;//将前指针置为头结点

for(int i=0;i<n;i++)//创建n个长度的链表

{

p=new jd;//创建新节点

p->next=NULL;//置空

pe->next=p;//连接

p->s=array[i];//赋值

pe=p;

}

p->next=head;

return head;

}


void delet(jd*head,int lo,int m)//删除第m个

{

jd*pe,*p;

int count=1,sum=0;

pe=head;

p=head->next;

while(lo!=0)//无元素时退出

{

if(p==head)

{

pe=pe->next;

p=p->next;

}

if(count==m)//删除等于m的节点

{

printf("第%-2d个出圈号数: %d号\n",++sum,p->s);

pe->next=p->next;

delete(p);

p=pe->next;//将p的地址赋为下一个地址

lo--;

count=0;//重置

}

else

{

pe=pe->next;

p=p->next;

}

count++;

}

}


int main()

{

int n,m;

int arr[1000];

for(int i=0;i<n;i++)//编号

{

arr[i]=i+1;

}

cout<<"请输入总人数n及出圈数m:"<<endl;

scanf("%d%d",&n,&m);

jd* l=creat(arr,n);//调用上述方法

delet(l,n,m);

return 0;

}

4.实验结果

5. 实验总结分析

通过这次实验,我进一步增强了对于链表的理解,也对链表的操作和实现更为熟悉。学习掌握了如何实现置空表、求表的长度、取结点、定位运算、插入运算、删除运算、建立不带头结点的单链表、建立带头结点的单链表、输出带头结点的单链表等操作。同时,通过查阅资料,请教同学,分析问题,解决问题,也锻炼了我实际操作时的动手能力。

  • 13
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值