约瑟夫环实验报告

合集下载

约瑟夫环实验报告

约瑟夫环实验报告

约瑟夫环实验报告约瑟夫环是一个经典的数学问题,它涉及到一个有趣的游戏。

这个游戏的规则是:有N个人站成一圈,从某个人开始,每报数到第M个人,就将该人从圈中移出去,再从下一个人开始重新报数,如此循环,直到只剩下一个人为止。

那么,我们将通过实验来探究一下约瑟夫环的性质和一些有趣的现象。

首先,我们设定了一组实验条件。

假设有10个人,从1到10编号,报数为3。

我们选择从编号为1的人开始报数,然后每次报数到第3个人。

接下来,我们按照约瑟夫环的规则进行实验。

实验开始后,我们可以观察到一系列有趣的现象。

首先,被淘汰的人并不会立即离开圈子,而是继续留在原位,但不再参与后续的报数和淘汰。

当每次报数到达M的倍数时,即到了第3个人、第6个人、第9个人等等,这些人就会被逐渐淘汰出圈。

在实验过程中,我们发现了一个有趣的规律。

剩下的人似乎总是固定按照一定的顺序被淘汰。

为了更好地观察这个规律,我们进行了多组实验,并记录了淘汰顺序。

首先,在报数为3的情况下,我们记录了当有10个人时的淘汰顺序。

开始时,第1轮淘汰的是第3个人,然后是第6个人,之后是第9个人。

接着,轮到第2个人被淘汰,然后是第7个人,最后是第1个人。

可见,在这个实验条件下,被淘汰的顺序是3、6、9、2、7、1。

我们可以看到,在最后几轮淘汰时,被淘汰的顺序逐渐回到了初始的编号1。

接着,我们将实验条件略作改变,观察是否会出现相似的淘汰顺序。

这次,我们依然有10个人,报数为4。

开始时,第1轮淘汰的是第4个人,然后是第8个人,之后是第2个人。

接着,轮到第5个人被淘汰,然后是第10个人,最后是第6个人。

通过这次实验,我们可以观察到一些不同之处。

尽管淘汰的顺序在最后几轮回到了初始的编号1,但淘汰的间隔变得更长了,而且整体的淘汰顺序也有了一定的变化。

通过对约瑟夫环实验的多次观察和记录,我们可以总结出一些结论。

首先,淘汰的顺序呈现出周期性,并在最后几轮回到了初始的编号。

其次,在不同的实验条件下,淘汰的规律可能会有所不同。

工作报告之约瑟夫环实验报告总结

工作报告之约瑟夫环实验报告总结

约瑟夫环实验报告总结【篇一:约瑟夫环实验报告】实验报告课程名称:数据结构实验名称:顺序表和链表的应用实验编号:实验一指导教师:一、实验目的(1)掌握线性表的基本操作(插入、删除、查找)以及线性表合并等运算在顺序存储结构、链式存储结构上的实现。

重点掌握链式存储结构实现的各种操作。

(2)掌握线性表的链式存储结构的应用。

二、实验内容与实验步骤(1)实验内容:实现约瑟夫环,约瑟夫环(joseph)问题的一种描述是:编号为1、2、3……n的n个人按照顺时针方向围坐一圈,每人持有一个密码(正整数)。

一开始任选一个正整数作为报数的上限值m,从第一个人开始按照顺时针的方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。

设计一个程序求出出列顺序。

(2)抽象数据类型和设计的函数描述,说明解决设想。

首先定义一个链表,用其中的data项存储每个人的编号,用password项存储每个人所持有的密码,并且声明一个指针。

之后使用creatlist_cl函数来创建一个循环链表,在其中的data和password中存入编号和密码,最后使最后一个节点的next指向l,使其能够形成循环队列。

定义了函数display来显示链表当中的内容,以确定存储的数据没有错误。

定义了函数delete_l来实现约瑟夫环中依次删除的功能,依次比较,如果某个人所持的密码和m值相等,则删除这个结点,并且输出此时该结点的编号和密码,实现出列的功能。

(3)简短明确地写出实验所采用的存储结构,并加以说明。

该实验我主要采用的是线性表的链式存储结构,首先定义了链表的结构,其中包括data项和password项,分别存储每个人的编号和所持密码,还声明了指向下一个结点的指针,该指针可以连接各个结点,并且将最后一个结点的指针指向第一个结点使之成为一个循环链表。

三、实验环境操作系统:windows 7调试软件名称:vc++版本号:6.0上机地点:综合楼311四、实验过程与分析(1)主要的函数或操作内部的主要算法,分析这个算法的时、空复杂度,并说明设计的巧班级:学号:姓名:组号:实验成绩:批阅教师签字:实验日期:实验时间:妙之处。

约瑟夫环问题实验报告

约瑟夫环问题实验报告

约瑟夫问题实验报告背景约瑟夫问题(Josephus Problem)据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。

然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

原题:用户输入M,N值,N个人围成一个环,从0号人开始数,数到M,那个人就退出游戏,直到最后一个人求最后一个剩下的人是几号?问题描述设编号为1-n的n(n>0)个人按顺时针方向围成一圈.首先第1个人从1开始顺时针报数.报m的人(m 为正整数).令其出列。

然后再从他的下一个人开始,重新从1顺时针报数,报m的人,再令其出列。

如此下去,直到圈中所有人出列为止。

求出列编号序列。

一.需求分析:(1)基本要求需要基于线性表的基本操作来实现约瑟夫问题需要利用循环链表来实现线性表(2)输入输出格式输入格式:n,m(n,m均为正整数,)输出格式1:在字符界面上输出这n个数的输出序列(3)测试用例(举例)输入:8,4输出:4 8 5 2 1 3 7 6二.概要设计(1)抽象数据类型:数据对象:n个整数数据关系:除第一个和最后一个n外,其余每个整数都有两个元素与该元素相邻。

基本操作:查找,初始化,删除,创建链表循环链表的存储结构:(2).算法的基本思想循环链表基本思想:先把n个整数存入循环链表中,设置第m个数出列,从第一个开始查找,找到第m个时,输出第m个数,并删掉第m个节点,再从下一个数开始查找,重复上一步骤,直到链表为空,结束。

(3).程序的流程程序由三个模块组成:1.输入模块:完成两个正整数的输入,存入变量n和m中2.处理模块:找到第m个数3.输出模块:按找到的顺序把n个数输出到屏幕上三.详细设计首先,设计实现约瑟夫环问题的存储结构。

实验报告 约瑟夫问题

实验报告 约瑟夫问题
pNew->next = pCur->next;
pCur->next = pNew;
pCur = pNew;
printf("结点%d,密码%d\n",pCur->id, pCur->cipher);
}
}
printf("完成单向循环链表的创建!\n");
}
(3)运行"约瑟夫环"问题
static void StartJoseph(NodeType **, int)
exit(-1);
}
pNew->id = iId;
pNew->cipher = iCipher;
pNew->next = NULL;
return pNew;
}
(6)测试链表是否为空,空为TRUE,非空为FALSE
static unsigned EmptyList(const NodeType *pHead)
实验内容
利用循环链表实现约瑟夫环求解。
实验说明
1.问题描述
约瑟夫问题的:编号为1,2,....,N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),一开始任选一个正整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数,报到M时停止报数。报M的人出列,将他的密码作为新的M值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
{
if(!pHead)
{
return TRUE;
}
return FALSE;
}
实验中遇到的问题及解决方法
实验结果如下:
实验总结(结果和心得体会)

约瑟夫环实验报告

约瑟夫环实验报告

约瑟夫环问题实验报告一、实验内容本实验利用单向循环链表模拟约瑟夫环问题(编号为1,2,…,n的n个人按顺时针方向围坐一圈,没人持有一个密码(正整数)。

开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始报数,报到m是停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止),按照出列顺序印出个人的编号。

M的初值为20,n=7,7个人的密码依次为3,1,7,2,4,8,4,首先m值为6。

二、源程序#include"stdafx.h"#include<iostream>using namespace std;#include<conio.h>//getch();/*write: Han.JH*/static int people_number_count; typedef struct People_Node{int Password_Data,people_number;struct People_Node *next;}People_Node,*People_LinkList;void GreatList(People_LinkList &L){People_Node *s,*r; int flag=1;int Password;L=new People_Node;L->next=NULL;r=L;while(flag==1){cout<<"输入每个人的密码,以回车作间隔,'0'表示结束:";cin>>Password;//输入每个人的密码;if(Password!=0){s=new People_Node;s->Password_Data=Password;people_number_count++; //对人的编号s->people_number=people_number_count;r->next=s;r=s;}else{ r->next=L->next;flag=0;}}}void GetList(People_LinkList &L){People_Node *r;int m,k;int count=0;cout<<"输入报数上限值m:";cin>>m;r=L;cout<<"出列排序:";while(count!=people_number_count){ //则所有人以出列,结束循环for(k=1;k<=m-1;k++){r=r->next;}count++;m=r->next->Password_Data;cout<<"["<<r->next->people_number<<"]";r->next=r->next->next;}}void main(){People_LinkList L;void GreatList(People_LinkList &);void GetList(People_LinkList &);cout<<"++++++++++++约瑟夫环问题+++++++++++"<<endl;GreatList(L);GetList(L);cout<<"[--结束--]"<<endl;getch();}三、调试刚开始调试时出现了无法打开<iostream.h>头文件的错误,经过上网查询,#include<iostream.h>是C语言风格,但是在标准 C 里面,是不用#include <iostream.h>的,而要使用#include <iostream>把#include<iostream.h>改为:#include<iostream>using namespace std;后,问题解决。

约瑟夫环-数据结构

约瑟夫环-数据结构

数据结构期末试验报告学院:专业:学号:班级:姓名:2010.12.12 Joseph约瑟夫环上机实验报告实验名称:joseph约瑟夫环题目要求的约瑟夫环操作:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

设计一个程序来求出出列顺序。

实验要求:1~)利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。

2~)建立输入处理输入数据,输入m的初值,n ,输入每个人的密码,建立单循环链表。

3~)建立一个输出函数,将正确的输出序列4~)测试数据:m的初值为20,n=7 ,7个人的密码依次为3,1,7,2,4,7,4,首先m=6,则正确的输出是什么?实验过程:1.基本算法以及分析:本程序主要是以建立单循环链表的形式,建立起一个约瑟夫环,然后根据之前创立的结点,输入结点里的一些数据,如下typedef struct Node{int Index; 在当前环中所处的位置,即编号int Password; 在当前环中的所带的密码struct Node *next;}JosephuNode;程序有主函数开始,首先,提示输入创建约瑟夫环环数以及每个环上所带的密码。

然后,开始调用JosephuNode *Creat_Node函数,利用单循环链表建立起约瑟夫环,tail->next = head;就是将最后一个结点的后继指向头结点,函数结尾return head; 将约瑟夫环的头指针返回,并将它赋值head,然后主函数继续调用Josephu函数,通过讲head和Password 引入函数,以建立两个嵌套循环输出并实现如下功能:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

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

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

约瑟夫环数据结构实验报告《约瑟夫环数据结构实验报告》摘要:本实验旨在通过使用约瑟夫环数据结构来模拟约瑟夫问题,并通过实验结果分析该数据结构的性能和适用场景。

实验结果表明,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且可以应用于一定范围的实际问题中。

1. 引言约瑟夫问题是一个经典的数学问题,描述了一个有n个人的圆桌围坐,从第一个人开始报数,报到m的人离开,然后从离开的人的下一个人开始重新报数,直到所有人离开。

在本实验中,我们将使用约瑟夫环数据结构来模拟这一问题,并分析其性能和适用场景。

2. 实验方法我们首先定义了一个约瑟夫环的数据结构,并实现了相应的插入、删除等操作。

然后,我们使用不同规模的数据集进行了实验,记录了每次操作的时间开销,并进行了性能分析。

3. 实验结果实验结果表明,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率。

在不同规模的数据集下,其操作时间基本保持在可接受的范围内,并且随着数据规模的增加,性能表现基本保持稳定。

4. 结论约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且可以应用于一定范围的实际问题中。

然而,在处理大规模数据时,仍需进一步优化算法和数据结构,以提高性能和效率。

5. 展望未来,我们将进一步研究约瑟夫环数据结构在实际问题中的应用,并探索其在其他领域的潜在价值。

同时,我们也将继续优化算法和数据结构,以提高其性能和适用范围。

综上所述,约瑟夫环数据结构在解决约瑟夫问题方面具有良好的性能和效率,并且具有一定的实际应用价值。

通过本实验,我们对该数据结构有了更深入的了解,并为其在实际问题中的应用提供了一定的参考和借鉴。

约瑟夫环 实验报告

约瑟夫环 实验报告

约瑟夫环实验报告约瑟夫环实验报告引言:约瑟夫环是一个经典的数学问题,它源自于古代传说。

根据传说,古代犹太人被罗马人围困在一个洞穴中,他们决定用一种特殊的方式来决定谁将成为首领。

他们站成一个圆圈,从一个人开始,每隔一个人杀掉一个,直到只剩下一个人。

这个问题被称为约瑟夫环问题,它在数学领域引起了广泛的研究和探讨。

实验目的:本实验旨在通过模拟约瑟夫环问题,探讨其数学规律和解法,并分析实验结果的意义和应用。

实验步骤:1. 首先,我们需要确定参与约瑟夫环的人数n和每次报数的间隔m。

在本次实验中,我们选择了n=10和m=3。

2. 接下来,我们将10个人按顺序排成一个圆圈,并给每个人编号,编号从1到10。

3. 实验开始时,从第一个人开始报数,每次报数到m的人将被淘汰出局。

4. 淘汰的人将离开圆圈,下一个人将从淘汰者的下一个人开始报数,继续进行报数和淘汰的过程,直到只剩下一个人为止。

实验结果:通过模拟实验,我们得到了以下结果:- 第一轮淘汰的人依次为:3、6、9、2、7、1、8、5、10。

- 第二轮淘汰的人依次为:4、9、2、8、5、1、7、6。

- 第三轮淘汰的人依次为:9、8、5、1、7、4、6。

- 第四轮淘汰的人依次为:1、7、4、6、9、5。

- 第五轮淘汰的人依次为:7、4、6、9、5。

- 第六轮淘汰的人依次为:4、6、9、5。

- 第七轮淘汰的人依次为:6、9、5。

- 第八轮淘汰的人依次为:9、5。

- 第九轮淘汰的人依次为:5。

结论:通过实验结果的分析,我们可以得出以下结论:1. 在本次实验中,最后幸存的人是编号为5的人。

2. 根据实验结果,我们可以总结出约瑟夫环问题的一般解法。

假设总人数为n,每次报数的间隔为m,最后幸存的人的编号可以通过递归公式f(n,m)=[f(n-1,m)+m]%n得到。

3. 约瑟夫环问题在数学中具有一定的研究价值和应用意义。

它涉及到递归、数论等数学概念和方法,可以帮助我们更好地理解和应用这些数学知识。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一.需求分析
1.约瑟夫环(Joseph)问题的一种描述是:编号为1,2……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。

2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,有用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在其后。

3.程序执行的命令包括:
1)输入初始密码和人数2)输入所有人的密码3)显示输入的所有人的编号及相应的密码4)输出出列密码及编号5)结束
4.测试数据
(1)m=20, n=7, 7个人的密码依次为3,1,7,2,4,8,4
(2)m=20,n=1
(3)m=20,n=0
前面一组为常规数据,后面两组为边缘数据
二、概要设计
为实现上述功能,应以有序单向循环链表表示约瑟夫环。

为此,需要有一个抽象数据类型。

该抽象数据类型的定义为:
ADT LinkList
{
数据对象:D={ ai | ai ∈termset,i=1,2,……n,n>=0},
termset中每个元素包含编号,密码,和一个指向下一节点的指针数据关系:R1={<ai-1,ai> | ai-1, ai ∈D , i=2,……n}
基本操作:
LinkList EvaluList(int n);//对单向循环链表进行尾插入赋值
int size(LinkList L);//求链表的节点个数
Status ScanList(LinkList L);//遍历单向循环链表
Status Joseph(LinkList &L,int m);//约瑟夫环的实现
}
此抽象数据类型中的一些常量如下:#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef double ElemType;
单向循环链表中节点的定义如下所示:typedef struct LNode
{
int number;
int data;
struct LNode *next;
}LNode, *LinkList;
三、详细设计
#include<iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef double ElemType;
//-----------------------------------
//定义单向循环链表
typedef struct LNode
{
int number;
int data;
struct LNode *next;
}LNode, *LinkList;
//-----------------------------------
LinkList EvaluList(int n);//对单向循环链表进行尾插入赋值
int size(LinkList L);//求链表的节点个数
Status ScanList(LinkList L);//遍历单向循环链表
Status Joseph(LinkList &L,int m);//约瑟夫环的实现
//-------------------------------------------------
void main()
{
int m,n;
cout<<"请输入初始密码(正整数)和人数"<<endl;
cin>>m>>n;
cout<<endl<<"请输入"<<n<<"个人的密码"<<endl<<endl;
LinkList L=EvaluList(n);
cout<<n<<"个人的密码为"<<endl;
ScanList(L);
cout<<n<<"个人的出列顺序为"<<endl;
Joseph(L,m);
}
//---------对单向循环链表进行尾插入赋值---------------- LinkList EvaluList(int n)
{
if(n==0)
return NULL;
int key;
cout<<"输入第1个人的密码";
cin>>key;
LinkList L=new LNode;
L->data=key;
L->number=1;
L->next=L;
for(int i=2;i<=n;i++)
{
LinkList p=new LNode;
int key;
cout<<"输入第"<<i<<"个人的密码";
cin>>key;
p->data=key;
p->number=i;
p->next=L->next;
L->next=p;
L=L->next;
}
cout<<endl;
L=L->next;
return L;
}
//---------------求链表的节点个数------------------- int size(LinkList L)
{
if(L==NULL)
return 0;
int i=1;
LinkList p=L->next;
while(p!=L)
{
i++;
p=p->next;
}
return i;
}
//---------------遍历单向循环链表--------------------
Status ScanList(LinkList L)
{
LinkList p=L;
if(p==NULL)
{
cout<<"人数为空"<<endl;
return FALSE;
}
cout<<"第1个人的密码";
cout<<p->data<<endl;
p=p->next;
while(p!=L)
{
cout<<"第"<<p->number<<"个人的密码";
cout<<p->data<<endl;
p=p->next;
}
cout<<endl;
return TRUE;
}
//----------------约瑟夫环的实现----------------------- Status Joseph(LinkList &L,int m)
{
if(L==NULL)
{
cout<<"人数为空,出列结束"<<endl;
return FALSE;
}
LinkList p=L;
while(p->next!=L)
p=p->next;
for(int n=size(L); n>0 ; n--)
{
cout<<"密码为"<<m<<",出列编号为";
for(int i=1; i<=m%n-1; i++)
p=p->next;
cout<<p->next->number<<endl;
m=p->next->data;
LinkList q=p->next;
p->next=q->next;
free(q);
}
return OK;
}
四、调试分析
1.当执行输入人数时,输入0程序出现了意想不到的错误,所以再重新设计时加入了对空节点的处理
2.在链表节点的设计上,最初是仅包含密码和指针,但是后来考虑到链表节点删除时会带来一系列的编号变化,编号难以确定,所以节点设计上又加了一个编号
3.在单向链表的赋值操作时,原本是以一个不变的L作为头结点,但是这种赋值方法带来了诸多变量设计的问题,所以将L为节点,赋值完成后,再让L指向头结点
4.程序原本是没有求节点个数的函数,但是在约瑟夫环的实现函数中,节点的个数时时影响着结果的判断,所以加入了该函数
5.考虑到时间问题,密码采用对剩余节点取余来减少遍历次数
6.当程序大体完成时,却又在调试过程中发现出列次序总是错误的,才想到第一次指向时应该让变化的指针指向尾节点,这样可以减少当密码为1时程序的设计量
五、测试结果
(第一组为常规数据,二、三两组为边缘数据)。

相关文档
最新文档