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

return count==0; } template <class T> bool SqList<T>::Full() const { return count==maxsize; } template <class T> int SqList<T>::Length() const { return count; } template <class T> void SqList<T>::Clear() { count=0; //这里并不是将所有元素删除,而是将元素个数置 0,实际上元素还在,但可以重新输入元素替换原来的元素 } template <class T> bool SqList<T>::SetElem(int position,const T &e) { if(position<1||position>Length()) //范围出错 { cout<<"范围出错,无法赋值!"<<endl; return false; } else { elems[position-1]=e; return true; } }
for(;i<=m;i++) { j++; if(j>len) j=1; while(S.GetElem(j)==0) { j++; if(j>len) j=1; } } if(j==0) j=1; cout<<S.GetElem(j)<<" "; S.SetElem(j,0); flag++; i=1; } cout<<endl; } return 0; } 测试用例:
数据结构:约瑟夫环实验报告

数据结构实验报告题目:约瑟夫环姓名:学号:专业班级:指导教师:课题工作时间:一.需求分析1.约瑟夫环(Joseph)问题的一种描述是:设有编号1,2,3。
n(n>0)的N个人围成一个圈,每个人持有一个密码(正整数)。
开始时从第k(1<=k<=n)个人按顺时针方向自1开始顺序报数,报到m(m为第K个人的密码)的人出圈,再以这个人顺时针方向上的下一个人的密码为m,并开始重新从1报数。
如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,有用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在其后。
3.测试数据(1)m=20, n=7, 结果依次为为3,1,7,2,4,8,4(2)m=20,n=1(3)m=20,n=0前面一组为常规数据,后面两组为边缘数据二、概要设计本程序是多文件程序,构成的函数有int main() 主函数,输出出队序列int initsuiji() 随机数产生初始化int suiji(int x,int y) 随机数产生函数int InitList(SqList &L) 初始化顺序表int ListInsert(SqList &L,int i,ElemType e) 在顺序表中插入元素int ListDelete(SqList &L,int i,ElemType &e) 删除顺序表中的元素int shunxu(int number) 顺序存储算法JosephuNode *Creat_Node(int numbers) 创建单循环链表void Josephu(JosephuNode *head,int Password) 添加元素信息int lianbiao(int number) 链表算法其中,void main()是最主要的函数,分别执行两种算法,并在执行的同时按照出列顺序输出元素信息(编号,密码),并在结尾输出两种算法执行所用的时间长短。
约瑟夫环-数据结构

实验二:Joseph(约瑟夫环)实验报告实验描述:编号为1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(报数上限)。
任意输入一个正整数作为报数上限值k(1<=k<=n),从第一个人开始顺时针方向报数,报到k时停止报数。
报k的人出列,然后从他下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
设计一个程序来求出出列顺序。
实验原理:先构造一个不带头结点的单循环链表,然后定义两个节点指针,第一个指针指向第一个节点,另一个指针指向第二个节点,并且使两个节点后移,每当结点计数到某一结点时,将他的前驱结点接到他的后继结点,再将此结点删除。
如此循环,直到两个节点重合(只有一个节点)时,循环结束。
实验过程:1.基本算法以及分析:1创建结点Node链表都是由一个个结点组成,由于结点的不同,组成的链表也不同。
因此需要创建链表结点。
结点结构体如下:2建立单循环链表每当结点计数到某一结点时,将他的前驱结点接到他的后继结点,再将此结点删除。
如此循环下去,直到最后变为空的单循环链表为止。
3程序的执行过程:程序有主函数开始,首先输入创建约瑟夫环节点数以及密码(报数上限)。
然后,开始调用JosephuNode *Creat_Node函数,利用单循环链表建立起约瑟夫环,函数结尾return head; 将约瑟夫环的头指针返回,并将它赋值head,然后主函数继续调用Josephu函数,通过将head和Password引入函数,以建立两个嵌套循环输出并得到结果。
2.程序源代码:#include <stdio.h>#include <malloc.h>typedef struct Node{int Index;struct Node *next;}JosephuNode;void main(){JosephuNode *Creat_Node(int numbers);void Josephu(JosephuNode *head,int Password);int numbers, Password;JosephuNode *head;printf("\n输入约瑟夫环问题的人数和起始密码:");scanf("%d,%d", &numbers, &Password);head=Creat_Node(numbers);printf("\n输出结果如下\n");Josephu(head,Password);}JosephuNode *Creat_Node(int numbers) // 使用单循环链表创建约瑟夫环{int i,pass;JosephuNode *head, *tail;head = tail = (JosephuNode *)malloc(sizeof(JosephuNode)); //申请头结点for (i = 1; i <numbers; i++){tail->Index = i;tail->next = (JosephuNode *)malloc(sizeof(JosephuNode));tail = tail->next; //指针指向下一个结点}tail->Index = i;tail->next = head; //建立循环return head;}void Josephu(JosephuNode *head,int Password) //数据结构{int i,j;JosephuNode *rear;for (i = 1; rear != head; i++){for (j = 1; j <Password; j++){rear = head;head = head->next;}rear->next = head->next;printf("\n第%d个出局的人的编号是:%d",i,head->Index);free(head);head = rear->next;}j=head->Index;printf("\n最后一个出局的人的编号是:%d\n ",j);free(head);}。
数据结构约瑟夫环实验报告

《数据结构与算法设计》约瑟夫环实验报告——实验一专业:物联网工程班级:物联网1班学号:15180118姓名:刘沛航一、实验目的1、熟悉VC环境,学习使用C语言利用链表的存储结构解决实际的问题。
2、在编程、上机调试的过程中,加深对线性链表这种数据结构的基本概念理解。
3、锻炼较强的思维和动手能力和更加了解编程思想和编程技巧。
二、实验内容1、采用单向环表实现约瑟夫环。
请按以下要求编程实现:①从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。
环表中的结点编号依次为1,2,……,m。
②从键盘输入整数s(1<=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) 抽象数据类型定义ADT Joh{数据对象:D={|,1,2,,,0}i i a a ElemSet i n n ∈=≥K数据关系:R1=11{,|,,1,2,,}i i i i a a a a D i n --<>∈=K基本操作:create(&J, n)操作结果:构造一个有n 个结点的单向环表J 。
show(J)初始条件:单向环表J 已存在。
操作结果:按顺序在屏幕上输出J 的数据元素。
calculate( J,s,n)初始条件:单向环表J 已存在,s>0,n>0,s<环表结点数。
操作结果:返回约瑟夫环的计算结果。
}ADT Joh(2)宏定义#define NULL 0#define OK 1#define ERROR -1(3)主程序流程(4)程序分为下述模块:1)主函数模块——执行输入调用其他的功能函数2)创建环表模块——创建单向环表3)计算处理模块——计算出要出列的标号并输出4)显示模块——输出建立好的环表调用关系如下:2、详细设计(1)数据类型设计typedef int ElemType; //元素类型typedef struct {ElemType data;struct Joh *next;}Joh, *LinkList,*p; //结点类型,指针类型(2)操作算法Status create(LinkList &J,int n){//创建一个有n个结点的单向环表if(n<=0)return ERROR; //n<0错误J=(LinkList)malloc(sizeof(J));J->data=1;J->next=J;//建立第一个结点for(int i=n;i>1;--i){p=(LinkList)malloc(sizeof(J));p->data=i;p->next=J->next;J->next=p;//插入到表头}return OK;}//createvoid show(LinkList J){//主要的操作函数//顺序输出环表J的结点p=J;printf("%d ",p->data);p=p->next;while(p!=J){ //循环终止条件printf("%d ",p->data);p=p->next;}}//showvoid calculate(LinkList J,int s,int n){p=J;Joh *head=p; //声明结点while(p->data!=s){p=p->next;head=p;}//寻找起始结点while(p->next!=p){ //终止条件for(int i=0;i<n-1;i++){head=p; //保存前置节点p=p->next;}printf("%d ",p->data);head->next=p->next; //删除已输出结点p=head->next;}if(n!=1)printf("%d\n",p->data);elseprintf("\n");}//calculate(3)主函数代码int main(){//主函数Joh *J;int m,s,n;printf("The num of node is:");scanf("%d",&m);create(J,m); //创建单向环表Jshow(J); //输出J的数据printf("\n");printf("The first node which you want is:");scanf("%d",&s);printf("The internal which you want is:");scanf("%d",&n);calculate(J,s,n); //计算并输出结果return 0;}//main四、程序调试分析1、细节决定成败,编程最需要的是严谨,如何的严谨都不过分,往往检查了半天发现错误发生在某个括号,分号,引号,或者数据类型上。
北邮数据结构实验-约瑟夫环

北邮数据结构实验-约瑟夫环数据结构实验报告实验名称:实验1——约瑟夫环学生姓名:班级:班内序号:学号:日期:1.实验要求实验目的:通过利用循环链表实现约瑟夫问题的求解进行实现,掌握如下内容:1.熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法2.学习指针、模板类、异常处理的使用3.掌握线性表的操作的实现方法4.学习使用线性表解决实际问题的能力实验内容:利用循环链表实现约瑟夫问题的求解。
约瑟夫问题如下:已知n个人(n>=1)围坐一圆桌周围,从1开始顺序编号。
从序号为1的人开始报数,顺时针数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规则重复下去,直到所有人全部出列。
请问最后一个出列的人的编号。
2. 程序分析2.1 存储结构首先构建结点的结构体,包括结点的编号number和指向后继元素的指针*next。
然后构建循环链表储存每一个结点。
2.2 关键算法分析1、关键算法:插入:用尾插法构建循环链表,建立一个尾指针r用来保存最后一个结点的地址,插入每一个节点后,r指向新插入的结点。
用for循环来给每一个结点的number赋值。
插入的步骤:1.建立新指针s;2.在for循环中给s赋值;3.将r指针指向s;4.修改尾指针r=s5.在全部结点插入后,将终端结点指向第一个指针,r->next=front->next。
约瑟夫环算法实现:1.因为每次循环都有一个人出列,最后只剩一个人,因此要进行n-1次循环,用for循环实现。
2.同时定义一个指针p=front->next,每次循环front和p均后移m-1个,使p指向每次循环的第m个人,front指向第m-1个人。
并输出出列的人的number,即p->number。
3.让front->next=p->next,删除p。
4.继续进行循环2、代码详细分析:约瑟夫环算法步骤:①定义一个指针p=front->next,每次循环front和p均后移m-1个,使p指向每次循环的第m个人,front指向第m-1个人。
约瑟夫环数据结构实验报告

约瑟夫环数据结构实验报告《约瑟夫环数据结构实验报告》摘要:本实验旨在通过使用约瑟夫环数据结构来模拟约瑟夫问题,并通过实验结果分析该数据结构的性能和适用场景。
实验结果表明,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且可以应用于一定范围的实际问题中。
1. 引言约瑟夫问题是一个经典的数学问题,描述了一个有n个人的圆桌围坐,从第一个人开始报数,报到m的人离开,然后从离开的人的下一个人开始重新报数,直到所有人离开。
在本实验中,我们将使用约瑟夫环数据结构来模拟这一问题,并分析其性能和适用场景。
2. 实验方法我们首先定义了一个约瑟夫环的数据结构,并实现了相应的插入、删除等操作。
然后,我们使用不同规模的数据集进行了实验,记录了每次操作的时间开销,并进行了性能分析。
3. 实验结果实验结果表明,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率。
在不同规模的数据集下,其操作时间基本保持在可接受的范围内,并且随着数据规模的增加,性能表现基本保持稳定。
4. 结论约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且可以应用于一定范围的实际问题中。
然而,在处理大规模数据时,仍需进一步优化算法和数据结构,以提高性能和效率。
5. 展望未来,我们将进一步研究约瑟夫环数据结构在实际问题中的应用,并探索其在其他领域的潜在价值。
同时,我们也将继续优化算法和数据结构,以提高其性能和适用范围。
综上所述,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且具有一定的实际应用价值。
通过本实验,我们对该数据结构有了更深入的了解,并为其在实际问题中的应用提供了一定的参考和借鉴。
约瑟夫环数据结构实验报告

约瑟夫环数据结构实验报告约瑟夫环数据结构实验报告引言约瑟夫环是一种经典的数学问题,它涉及到一个有趣的数据结构。
本次实验旨在通过实现约瑟夫环数据结构,深入理解该问题,并探索其在实际应用中的潜力。
本报告将介绍实验的设计和实现过程,并分析实验结果。
实验设计在本次实验中,我们选择使用链表来实现约瑟夫环数据结构。
链表是一种非常灵活的数据结构,适合用于解决约瑟夫环问题。
我们设计了一个Josephus类,其中包含了创建环、添加元素、删除元素等操作。
实验实现1. 创建环在Josephus类中,我们首先需要创建一个循环链表。
我们使用一个头节点来表示环的起始位置。
在创建环的过程中,我们可以选择指定环的长度和起始位置。
2. 添加元素在创建环之后,我们可以通过添加元素来向约瑟夫环中插入数据。
我们可以选择在环的任意位置插入元素,并且可以动态地调整环的长度。
3. 删除元素根据约瑟夫环的规则,每次删除一个元素后,下一个元素将成为新的起始位置。
我们可以通过删除元素的操作来模拟约瑟夫环的运行过程。
在删除元素时,我们需要考虑环的长度和当前位置。
实验结果通过实验,我们得出了以下结论:1. 约瑟夫环数据结构可以有效地模拟约瑟夫环问题。
通过创建环、添加元素和删除元素的操作,我们可以模拟出约瑟夫环的运行过程,并得到最后剩下的元素。
2. 约瑟夫环数据结构具有一定的应用潜力。
除了解决约瑟夫环问题,该数据结构还可以用于其他类似的问题,如任务调度、进程管理等。
3. 约瑟夫环数据结构的时间复杂度较低。
由于约瑟夫环的特殊性质,我们可以通过简单的链表操作来实现该数据结构,使得其时间复杂度较低。
结论本次实验通过实现约瑟夫环数据结构,深入理解了该问题,并探索了其在实际应用中的潜力。
通过创建环、添加元素和删除元素的操作,我们可以模拟出约瑟夫环的运行过程,并得到最后剩下的元素。
约瑟夫环数据结构具有一定的应用潜力,并且具有较低的时间复杂度。
通过本次实验,我们对数据结构的设计和实现有了更深入的理解,并为将来的研究和应用奠定了基础。
数据结构约瑟夫环实习报告

数据结构约瑟夫环实习报告一、实习题目约瑟夫环(Josephus Problem)是一种经典的问题,编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数,报到M时停止报数。
报M的人出列,将他的密码作为新的M值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序,并利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各人的编号。
二、实习目的1. 熟悉单向循环链表的存储结构及其应用。
2. 加深对线性链表这种数据结构的基本概念理解。
3. 锻炼较强的思维和动手能力,更加了解编程思想和编程技巧。
三、实习内容1. 采用单向循环链表实现约瑟夫环。
2. 从键盘输入整数m,通过create函数生成一个具有m个结点的单向循环链表。
3. 从键盘输入整数s(1<s<m)和n,从环表的第s个结点开始计数为1,当计数到第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点的下一个结点开始重新计数到n,如此循环,直到输出了这个环表的全部结点为止。
四、程序设计1. 概要设计为了解决约瑟夫环的问题,我们可以建立单向循环链表来存储每个人的信息(该人的编号以及其下一个人的编号),及结点,人后通过查找每个结点,完成相应的操作来解决约瑟夫问题。
抽象数据类型定义:数据对象:D数据关系:R1基本操作:操作结果:构造2. 详细设计(1)初始化循环单链表```cvoid initList(LNode *head) {head->next = head;head->number = 0;}```(2)尾插法建立循环单链表```cvoid createFromTail(LNode *head, int m, int pass, int length) { LNode *p = head;int i;for (i = 1; i <= m; i++) {LNode *s = (LNode *)malloc(sizeof(LNode));s->number = i;s->pass = pass;s->next = NULL;p->next = s;p = s;}p->next = head; // 使链表形成一个环}```(3)从链表中删除结点```cvoid deleteFromList(LNode *head, LNode *p) {if (p->next == head) { // 删除的是头结点head = p->next;}p->next = p->next->next;free(p);}```(4)约瑟夫计数```cvoid yuesefu(LNode *head, int m, int n, int *sequence) { int count = 0;LNode *p = head;while (p->next != p) { // 当链表中还有多个结点时循环 count = 0;LNode *q = p->next;while (count < n) {q = q->next;count++;}sequence[count] = q->number; // 记录下出列的人的编号deleteFromList(head, q); // 删除该结点p = q->next; // 从下一个结点又开始计算n = m; // 新的M值}}```五、实验结果与分析通过以上程序设计,我们可以得到约瑟夫环的出列顺序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》课程实验报告书
姓名:_____**_________
学号:____**********____
专业:____物联网工程____
班级:_____1604________
2017 年 10 月 15 日
一、实验目的
1.掌握线性表特性
2.熟练掌握线性表的基本操作
3. 利用线性表设计算法并实现
二、实验内容
1.解决约瑟夫环问题:已知n 个人(以编号1,2,3...n 分别表示)围坐在一张圆桌周围。
从编号为k 的人开始报数,数到m 的那个人出列;他的下一个人又从1开始报数,数到m 的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
2.基本要求:1)根据题目要求设计解决约瑟夫环应用问题的数据结构。
2)要求采用C++编程语言实现设计的算法。
三、设计思路
1.
可将人的顺序简单编号,从1到n ;
构造一个循环链表,可以解决首位相连的问题;
将人的编号插入到结构体的
Data 域中; 遍历人的编号,输出参与的人的编号;
开始报数,从头报数,报到k 的人出局(删除此结点),并释放此结点。
直到人数只有一个人时,退出循环,输出获胜的人。
2.存储结构设计
(循环结束条件)
3.算法的核心思想说明
确定需要删除的位置;
设置并删除该位置。
已知报数间隔m,我们可以把当前位置加上m获得需要删除的位置,如果获得的位置超过顺序表中实际元素的总长度,则可以通过减去数组的实际长度来修正修正(即模拟环状计数)。
然后把顺序表中的当前指向位置设置为该位置,继而删掉该位置。
反复进行上述确定位置和删除位置的操作,直到顺序表为空。
四、数据结构设计
1.类的声明和定义(要求给出完整的类声明和核心成员函数的定义)
#ifndef Joseph_H
#define Joseph_H
#include<iostream>
using namespace std;
struct Node//结点
{
int data;//存储数据
Node *next;//下一个节点的地址
};
class CircularLinkList//单向循环链表类
{
public:
CircularLinkList()//构造函数
{
first = new Node;
first->data = NULL;
first->next = first;
}
~CircularLinkList() { delete first; }//析构函数
void CreateLinkList(int a[], int n); //创建单向循环链表
void PrintLinkList(); //遍历链表
void Joseph(int k,int n); //约瑟夫环实现
private:
Node *first;
};
#endif
2.算法实现
#include"Joseph.h"
#include<windows.h>
#include<iomanip>
void CircularLinkList::CreateLinkList(int a[], int n)
{
Node *s, *r = first;//尾指针初始化
for (int i = 0;i < n;i++)//尾插法
{
s = new Node;
s->data = a[i];
r->next = s;
r = s;
}
r->next = first->next;//循环
}
void CircularLinkList::PrintLinkList()
{
int count = 0;//计数器
Node *r = first->next;
do {
cout <<setw(3)<< r->data;
count++;
r = r->next;
if (count % 10 == 0)
cout << endl<<" ";
} while (r != first->next);//当链表循环到第一节点时跳出循环
cout << endl;
}
void CircularLinkList::Joseph(int k,int n)
{
int m;
cout <<" -->>请输入约瑟夫密码:" ;
cin >> m;//输入约瑟夫密码
Node *pre, *p;
pre = first;//工作指针初始化
p = pre->next;
for (int i = 0;i < k-1;i++)
{
pre = pre->next;
p = pre->next;
}
int count = 1;//计数器初始化,约瑟夫问题至少有两个成员
cout <<" ***************************************************\n";
while (pre != p)
{
if (count == m)//如果计数器等于密码
{
Sleep(1 * 1000);//执行挂起一段时间(1秒)
cout <<setw(26)<< p->data <<"号死亡!"<< endl;//显示结果
Node *q = p;
pre->next = p->next;
delete q;//删除死亡结点
p = pre->next;
count = 1;//计数器重新计数
}
else
{
pre = pre->next;//工作指针后移
p = p->next;
count++;//计数器加一
}
}
cout <<" ***************************************************\n";
cout <<setw(26)<< p->data <<"号存活!"<< endl;//显示最后存活的
delete p;//删除结点p
system("pause");
}
五、程序测试与实现
1.程序在调试过程中出现的问题及解决办法
2.程序运行过程及结果界面
六、实验调试
七、问题及解决方法
问题:无法从第k个人开始报数。
解决方法:用while循环,找寻开始报数的编号k,找到后把他报的数标记为1. 问题:将LinkList.h文件的LinkList类中的行为函数放进LinkList.cpp文件中出现错误“重定义”。
解决办法:将行为函数的定义与声明均放进LinkList.h文件中。
八、心得体会
通过对约瑟夫环问题算法的设计,我加深了对数据结构及存储结构的理解,进一步的理解了课本中所学的各种数据结构,尤其是对单链表上基本运算的体现,学会了如何使用循环链表,比如建立一个循环链表,删除链表中的一个结点,增加一个结点等等。
另外,写代码一定要细心仔细,不能犯不该犯的粗心的错误!
注(格式要求):1)字体采用楷书小四号字,行间距为固定值20磅
2)代码用Time New Roman字号为五号,行间距固定值16磅。