数据结构课程设计约瑟夫环报告

合集下载

实验报告——约瑟夫环

实验报告——约瑟夫环

《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:约瑟夫环姓名:张光栋院系:计算机学院专业:网络工程年级:2013级学号:13055532指导教师:张纪林一、需求分析1.以单项循环链表存储结构模拟约瑟夫环问题。

即编号为1、2、3…、n的n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

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

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

按出列顺序印出各人的编号。

2.演示程序以用户与计算机的对话方式执行,用户输入相应的数据,输出结果显示在其后。

3.测试数据:(1)n=55个人的密码依次为:2,4,2,6,2;首先m值为2(正确的输出顺序为:2 1 4 3 5)(2)n=77个人的密码依次为:2,4,1,4,3,2,3首先m值为5(正确的输出顺序为:5 1 3 4 6 2 7)二、概要设计为实现上述程序功能,可利用单向循环链表存储结构模拟此过程。

1.单向循环链表的抽象数据类型定义为:ADT CircularList{数据对象:D={ai|ai∈LNode,i=1,2,…,n,n≥0}数据关系:R1={<ai-1,ai>|ai-1∈D,i=2,…,n}基本操作:Status LisCreate_L(LinkList &L,int I,ElemType &e)操作结果:在不带头结点的单链表L中,创建第i个元素,并用e赋值}2.本程序中包括的两个基本模块:1)主程序模块:Void main(){初始化;do{接受命令;处理命令;}while(“命令”=”退出”)}2)循环链表模块:实现循环链表的抽象数据结构三、详细设计1.结点类型typedef struct ListNode{int mi;int n;struct ListNode *next;}ListNode,*LinkList;2.用循环链表存储约瑟夫环,没有头结点,基本操作函数如下:void CreateList(LinkList&L, int n){LinkList s;int i;L=(LinkList)malloc(sizeof(ListNode));L->n=1;L->next=L;for(i=2;i<=n;i++){s=(LinkList)malloc(sizeof(ListNode));s->next=L->next;L->next=s;s->n=i;L=L->next;}}void Delete(LinkList L, int m){int i;LinkList p,q;p=L;while(p->next!=p){for(i=1;i<m;i++)p=p->next;q=p->next;m=q->mi;printf("%d ",q->n);p->next=q->next;free(q);}printf("%d ",p->n);free(p);}3.主函数:int main(){int n,i,m;LinkList L,p;printf("请输入人数:");scanf("%d",&n);CreateList(L,n);printf("请输入密令\n");p=L->next;for(i=1;i<=n;i++){printf("请输入第%d条密令\n",i);scanf("%d",&p->mi);p=p->next;}printf("请输入初始密令\n");scanf("%d",&m);printf("输出为\n");Delete(L, m);return 0;}四、调试分析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个数输出到屏幕上三.详细设计首先,设计实现约瑟夫环问题的存储结构。

C++数据结构之约瑟夫环

C++数据结构之约瑟夫环

2009级数据结构实验报告实验名称:实验线性表实现约瑟夫问题求解学生姓名:桂柯易班级:2009211120班内序号:07学号:09210580日期:2010年10月31日1.实验要求【实验目的】1.熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法;2.学习指针、模板类、异常处理的使用;3.掌握线性表的操作实现方法;4.培养使用线性表解决实际问题的能力。

【实验内容】利用循环链表实现约瑟夫问题的求解。

约瑟夫问题如下:已知n个人(n>=1)围坐一圆桌周围,从1开始顺序编号。

从序号为1的人开始报数,顺时针数到m的那个人出列。

他的下一个人又从1开始报数,数到m 的那个人又出列。

依此规则重复下去,直到所有人全部出列。

请问最后一个出列的人的编号。

2.程序分析2.1 存储结构存储结构:循环链表2.2 关键算法分析【设计思想】首先,设计实现约瑟夫环问题的存储结构。

由于约瑟夫环本身具有循环性质,考虑采用循环链表,为了统一对表中任意节点的操作,循环链表不带头结点。

循环链表的结点定义为如下结构类型:struct Node{int number;Node *next;};其次,建立一个不带头结点的循环链表并由头指针first指示。

最后,设计约瑟夫环问题的算法。

【伪代码】1、工作指针first,r,s,p,q初始化2、输入人数(n)和报数(m)3、循环n次,用尾插法创建链表Node *q;for(int i=1;i<=n;i++){Node *p;p=new Node;p->number=i;p->next=NULL;if(i==1) L=q=p;else{q->next=p;q=q->next;}}q->next=L;if(L!=NULL){return(L);}4、输入报数的起始人号数k;5、Node *q = new Node;计数器初始化i=1;6、循环n次删除结点并报出位置(其中第一个人后移k个)当i<n时移动指针m-2次p=p->next;删除p结点的后一结点qq=p->next;p->next=q->next;*L = p->next;报出位置后Delete q;计数器i++;【复杂度】for(int i=1;i<=n;i++){Node *p;p=new Node;p->number=i;p->next=NULL;if(i==1) L=q=p;else{q->next=p;q=q->next;}时间复杂度:O(n)if(i==1) i+=LengthList(*L);Node *p;p=*L;int j=0;while(j<i-2) {p=p->next;j++;}q = p->next;p->next=p->next->next;*L = p->next;return(q);时间复杂度:O(n2)算法的空间复杂度:O(n2)2.3 其他程序源代码:#include<iostream>using namespace std;struct Node//循环节点的定义{int number;//编号Node *next;};Node *CreateList(Node *L,int &n,int &m);//建立约瑟夫环函数void Joseph(Node *L,int n,int m);//输出每次出列号数函数Node *DeleteList(Node **L,int i,Node *q);//寻找每次出列人的号数int LengthList(Node *L);//计算环上所有人数函数void main()//主函数{Node *L;L=NULL;//初始化尾指针int n, m;cout<<"请输入人数N:";cin>>n;//环的长度if(n<1){cout<<"请输入正整数!";}//人数异常处理else{cout<<"请输入所报数M:";cin>>m;if(m<1){cout<<"请输入正整数!";}//号数异常处理else{L=CreateList(L,n,m);//重新给尾指针赋值Joseph(L,n,m);}}system("pause");}Node *CreateList(Node *L,int &n,int &m)//建立一个约瑟夫环(尾插法){Node *q;for(int i=1;i<=n;i++){Node *p;p=new Node;p->number=i;p->next=NULL;if(i==1) L=q=p;//工作指针的初始化else{q->next=p;q=q->next;}}q->next=L;if(L!=NULL){return(L);}//返回尾指针else cout<<"尾指针异常!"<<endl;//尾指针异常处理}void Joseph(Node *L,int n,int m)//输出每次出列的人{int k;cout<<"请输入第一个报数人:";cin>>k;if(k<1||k>n){cout<<"请输入1-"<<n<<"之间的数"<<endl;} else{cout<<"\n出列顺序:\n";for(int i=1;i<n;i++){Node *q = new Node;if(i==1) q=DeleteList(&L,k+m-1,q);//第一个出列人的号数else q=DeleteList(&L,m,q);cout<<"号数:"<<q->number<<endl;delete q;//释放出列人的存储空间}cout<<"最后一个出列号数是:"<<L->number<<endl;;//输出最后出列人的号数}}Node *DeleteList(Node **L,int i,Node *q) //寻找每次出列的人{if(i==1) i+=LengthList(*L);//顺序依次出列情况的处理方式Node *p;p=*L;int j=0;while(j<i-2) {p=p->next;j++;}q = p->next;p->next=p->next->next;*L = p->next;return(q);}int LengthList(Node *L)//计算环上的人数{if(L){cout<<"尾指针错误!"<<endl;}//异常处理else{int i=1;Node *p=L->next;while(p!=L){i++;p=p->next;}return(i);}}3.程序运行结果1.测试主函数流程:2.测试条件:如上图所示,人数为20人,所报数为6,第一个报数的人是1号。

数据结构实验一 约瑟夫环问题实验报告电子版

数据结构实验一  约瑟夫环问题实验报告电子版
pri = head ;
for(i = 1;i<length;i++){
tmp = (Node *)malloc(sizeof(Node));
tmp->number = num[i];
tmp->pass = pas[i];
pri->next = tmp;
pri = tmp;
pri->next = head;
for(i=0;i<time;i++){ //找到要删除的结点
tmp = tmp->next;
}
printf("%d ",tmp->number);
timeห้องสมุดไป่ตู้= tmp->pass - 1;
deleteFromList(&head,tmp);//删除结点
tmp = tmp->next;//从下一个结点又开始计算
initList(head);
createFromTail(head,num,pas,sizeof(num)/sizeof(num[0]));
p = head;
printf("\n约瑟夫计数前,每个数和他的密码:\n");
for(i = 0;i<sizeof(num)/sizeof(num[0]);i++){
}
}
// 从链表中删除
void deleteFromList(List *head,Node *tmp)
{
Node *tmp1;
Node *tmp2;
tmp1 = *head;
tmp2 = tmp1;
//如果链表剩了一个元素

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

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

约瑟夫环数据结构实验报告约瑟夫环数据结构实验报告引言约瑟夫环是一种经典的数学问题,它涉及到一个有趣的数据结构。

本次实验旨在通过实现约瑟夫环数据结构,深入理解该问题,并探索其在实际应用中的潜力。

本报告将介绍实验的设计和实现过程,并分析实验结果。

实验设计在本次实验中,我们选择使用链表来实现约瑟夫环数据结构。

链表是一种非常灵活的数据结构,适合用于解决约瑟夫环问题。

我们设计了一个Josephus类,其中包含了创建环、添加元素、删除元素等操作。

实验实现1. 创建环在Josephus类中,我们首先需要创建一个循环链表。

我们使用一个头节点来表示环的起始位置。

在创建环的过程中,我们可以选择指定环的长度和起始位置。

2. 添加元素在创建环之后,我们可以通过添加元素来向约瑟夫环中插入数据。

我们可以选择在环的任意位置插入元素,并且可以动态地调整环的长度。

3. 删除元素根据约瑟夫环的规则,每次删除一个元素后,下一个元素将成为新的起始位置。

我们可以通过删除元素的操作来模拟约瑟夫环的运行过程。

在删除元素时,我们需要考虑环的长度和当前位置。

实验结果通过实验,我们得出了以下结论:1. 约瑟夫环数据结构可以有效地模拟约瑟夫环问题。

通过创建环、添加元素和删除元素的操作,我们可以模拟出约瑟夫环的运行过程,并得到最后剩下的元素。

2. 约瑟夫环数据结构具有一定的应用潜力。

除了解决约瑟夫环问题,该数据结构还可以用于其他类似的问题,如任务调度、进程管理等。

3. 约瑟夫环数据结构的时间复杂度较低。

由于约瑟夫环的特殊性质,我们可以通过简单的链表操作来实现该数据结构,使得其时间复杂度较低。

结论本次实验通过实现约瑟夫环数据结构,深入理解了该问题,并探索了其在实际应用中的潜力。

通过创建环、添加元素和删除元素的操作,我们可以模拟出约瑟夫环的运行过程,并得到最后剩下的元素。

约瑟夫环数据结构具有一定的应用潜力,并且具有较低的时间复杂度。

通过本次实验,我们对数据结构的设计和实现有了更深入的理解,并为将来的研究和应用奠定了基础。

数据结构课程设计约瑟夫环

数据结构课程设计约瑟夫环

《数据结构》课程设计报告书题目:约瑟夫环系别:计算机科学与应用学号:学生姓名:指导教师:完成日期:2012年6月7日目录1.需求分析 (3)1.1 功能分析 (3)1.2开发平台 (3)2.概要设计 (3)3. 程序设计主要流程 (5)4.调试与操作说明 (5)4.1调试情况 (5)4.2操作说明 (6)总结 (8)致谢 (9)附录 (9)参考文献 (13)指导教师评语: (14)1.需求分析1.1 功能分析本次选做的课程设计是改进约瑟夫(Joseph)环问题。

约瑟夫环问题是一个古老的数学问题,本次课题要求用程序语言的方式解决数学问题。

此问题仅使用单循环链表就可以解决此问题。

在建立单向循环链表时,因为约瑟夫环的大小由输入决定。

为方便操作,我们将每个结点的数据域的值定为生成结点时的顺序号和每个人持有的密码。

进行操作时,用一个指针r指向当前的结点,指针H指向头结点。

然后建立单向循环链表,因为每个人的密码是通过scanf()函数输入随机生成的,所以指定第一个人的顺序号,找到结点,不断地从链表中删除链结点,直到链表剩下最后一个结点,通过一系列的循环就可以解决改进约瑟夫环问题。

1.2开发平台WindowsXP操作系统;Microsoft Visual C++ 6.0;2.概要设计编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。

这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。

r->next=H。

解决问题的核心步骤:首先建立一个具有n个链结点,无头结点的循环链表。

然后确定第1个报数人的位置。

最后不断地从链表中删除链结点,直到链表为空。

约瑟夫环 实验报告

约瑟夫环 实验报告

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

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

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

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

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

实验步骤: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世纪,当时犹太人正面临罗马的入侵。

为了避免被俘虏,一群犹太士兵决定以一种特殊的方式自杀,而不是被罗马人俘虏。

他们围成一个圈,按照某个规则进行自杀,直到只剩下一个人为止。

这就是著名的约瑟夫环问题。

在这个问题中,我们有n个人,编号从1到n,围成一个圈。

按照一定的规则,从第一个人开始报数,每次报到m的人将被淘汰。

然后,从下一个人开始重新报数,如此循环,直到只剩下一个人为止。

这个问题的解决方法有很多,其中最常见的是使用链表数据结构。

我们可以将每个人表示为一个节点,节点之间通过指针连接,形成一个环形链表。

每次淘汰一个人后,只需要将指针跳过被淘汰的节点,重新连接链表。

为了更好地理解这个问题,我们可以通过一个简单的例子来演示。

假设有10个人,编号从1到10,每次报数到3的人将被淘汰。

首先,我们将这10个人表示为一个环形链表:1->2->3->4->5->6->7->8->9->10->1。

按照规则,第一次报数到3的人是3号,所以我们将3号节点从链表中删除:1->2->4->5->6->7->8->9->10->1。

接下来,从4号节点开始重新报数。

第二次报数到3的人是6号,所以我们再次将6号节点从链表中删除:1->2->4->5->7->8->9->10->1。

以此类推,直到只剩下一个人为止。

通过这个例子,我们可以看到约瑟夫环问题的解决方法非常简单直观。

使用链表数据结构,每次淘汰一个人后,只需要将指针跳过被淘汰的节点,重新连接链表。

这种方法的时间复杂度为O(n*m),其中n为人数,m为报数的次数。

除了链表,还有其他数据结构可以用来解决约瑟夫环问题。

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

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

数据结构实验报告约瑟夫环约瑟夫环是一个经典的问题,涉及到数据结构中的循环链表。

在本次数据结构实验中,我们将学习如何使用循环链表来解决约瑟夫环问题。

约瑟夫环问题最早出现在古代,传说中的犹太历史学家约瑟夫斯·弗拉维奥(Josephus Flavius)在围攻耶路撒冷时,为了避免被罗马人俘虏,与其他39名犹太人躲进一个洞穴中。

他们决定宁愿自杀,也不愿被敌人俘虏。

于是,他们排成一个圆圈,从第一个人开始,每次数到第七个人,就将他杀死。

最后剩下的人将获得自由。

在这个问题中,我们需要实现一个循环链表,其中每个节点表示一个人。

我们可以使用一个整数来表示每个人的编号。

首先,我们需要创建一个循环链表,并将所有人的编号依次添加到链表中。

接下来,我们需要使用一个循环来模拟每次数到第七个人的过程。

我们可以使用一个指针来指向当前节点,然后将指针移动到下一个节点,直到数到第七个人为止。

一旦数到第七个人,我们就将该节点从链表中删除,并记录下该节点的编号。

然后,我们继续从下一个节点开始数数,直到只剩下一个节点为止。

在实现这个算法时,我们可以使用一个循环链表的数据结构来表示约瑟夫环。

循环链表是一种特殊的链表,其中最后一个节点的指针指向第一个节点。

这样,我们就可以实现循环遍历链表的功能。

在实验中,我们可以使用C语言来实现循环链表和约瑟夫环算法。

首先,我们需要定义一个节点结构体,其中包含一个整数字段用于存储编号,以及一个指针字段用于指向下一个节点。

然后,我们可以实现创建链表、添加节点、删除节点等基本操作。

接下来,我们可以编写一个函数来实现约瑟夫环算法。

该函数接受两个参数,分别是参与游戏的人数和每次数到第几个人。

在函数内部,我们可以创建一个循环链表,并将所有人的编号添加到链表中。

然后,我们可以使用一个循环来模拟每次数到第几个人的过程,直到只剩下一个节点为止。

在每次数到第几个人时,我们可以删除该节点,并记录下其编号。

最后,我们可以返回最后剩下的节点的编号。

约瑟夫环问题实验报告

约瑟夫环问题实验报告
}
//报数为m的人出列
while(n--)
{
for(int s=m-1; s--; r=p, p = p->link);
cout << "The output is: " << p->data << endl;
r->link = p->link;
LinkList d = new LNode;
if(!d)
二、实验问题描述
设编号为1,2,···,n的n个人围坐一圈,约定编号为k(1≤k≤n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。
3、实验步骤
1、实验问题分析
①由于当某个人退出圆圈后,报数的工作要从下一个人开始继续,剩下的人仍要是围成一个圆圈,可以使用循环表;由于退出圆圈的工作对应着表中结点的删除操作,对于这种删除操作频繁的情况,应该选用效率较高的链表结构;为了程序指针每一次都指向一个具体的代表一个人的结点而不需要进行判断,链表不带表头结点。所以,对于所有人围成的圆圈所对对应的数据结构采用一个不带头结点的循环链表来描述。设头指针为p,并根据具体情况移动
可以采用数据类型定义: Typedef struct node {
int number;
struct node *next; }Lnode,*Linklist;
②为了记录退出的人的先后顺序,采用一个顺序表进行存储,程序结束后再输入依次退出的人的编号顺序。由于只记录各个结点的number值就可以,所以定义一个整型一维数组。如“int quite[N];”N为一个根据实际问题定义的一个足够大的整数。

约瑟夫环实验报告

约瑟夫环实验报告

约瑟夫环实验报告约瑟夫环(Josephus problem)是一个非常经典的数学问题,其得名于公元1世纪的犹太历史学家约塞夫斯(Josephus)。

约瑟夫环问题描述如下:n个人围坐成一个圆圈,从一些人开始依次报数,每报到第m个人,该人就被淘汰出圆圈,然后从下一个人重新开始报数。

直到剩下最后一个人时,即为问题的解。

例如,当n=7,m=3时,最后剩下的是4号人。

本次实验的目的是研究约瑟夫环问题的解决方法,并通过编程实现给定n和m的情况下找到最后的获胜者。

首先,我们需要分析问题的特点。

当n=1时,该问题的解即为最后剩下的人;当n>1时,最后剩下的人可以通过前一轮问题的解(剩下n-1个人的情况下)推导出来。

我们可以将解决该问题的方法分为两种:递归法和迭代法。

一、递归法递归法是通过问题的子问题来解决原问题。

对于约瑟夫环问题来说,递归法的解题思路如下:1.当n=1时,问题的解即为1;2.当n>1时,问题的解为(找到n-1个人时的解+m-1)对n取模,即((f(n-1,m)+m-1)%n)+1二、迭代法迭代法通过循环来解决问题,不断更新当前的解,直到问题得到解决。

对于约瑟夫环问题来说,迭代法的解题思路如下:1.初始化一个长度为n的数组a,a[i]=1表示第i个人还在圆圈中,a[i]=0表示第i个人已经被淘汰出圆圈;2. 从第一个人开始计数,每报数到第m个人,则将该人设为已淘汰,并计数器count加1;3. 重复步骤2,直到count=n-1;4.循环遍历数组a,找到最后剩下的人。

为了更加直观地展示实验结果,我们通过Python编写下述代码:```python#递归法解决约瑟夫环问题def josephus_recursive(n, m):if n == 1:return 1else:return (josephus_recursive(n - 1, m) + m - 1) % n + 1#迭代法解决约瑟夫环问题def josephus_iterative(n, m):a=[1]*ncount = 0i=0while count < n - 1:if a[i] == 1:j=0while j < m:if a[(i + j) % n] == 1:j+=1else:j=0i=(i+1)%na[(i-1)%n]=0count += 1for i in range(n):if a[i] == 1:return i + 1#测试递归法解决约瑟夫环问题print(josephus_recursive(7, 3)) # 输出4 #测试迭代法解决约瑟夫环问题print(josephus_iterative(7, 3)) # 输出4 ```通过以上代码,我们可以得到n=7,m=3时,最后剩下的人是4号人。

数字结构实验约瑟夫环的实验报告

数字结构实验约瑟夫环的实验报告

约瑟夫环一、目的(本次实验所涉及并要求掌握的知识点)熟练掌握线性表的基本操作在两种储存结构上的实现,其中以各种链表的操作和应用作为重点内容。

二、实验内容与设计思想(设计思路、主要数据结构、主要代码结构、主要代码段分析、电路图)1.问题描述:约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。

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

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

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

2.基本要求:利用单向循环链表储存结构模拟此过程,按照出列的顺序印出各人的编号。

3.要求:程序运行后,首先要求用户指定出事报数上限值,然后读取各人的密码。

可设n ≦30。

此题所用的循环链表中不需要“头结点”,请注意空表和非空表的界限。

三、实验使用环境(本次实验所使用的平台及软件)本次实验在VC++6.0环境下调试。

四、程序源代码#include<stdio.h>#include<stdlib.h>typedef struct node{int num; //结点的编号int cipher; //密码struct node *next;}linklist;typedef linklist *head; //链表void main(){int n,m,i,j,k;linklist *head=(linklist*)malloc(sizeof(linklist));//开辟一个空间,并将它的起始地址赋给头指针head//linklist *p1,*p2;printf("请输入队列人数");scanf("%d",&n);//输入总人数//printf("请输入初始报数值:");scanf("%d",&m);//输入初始报数值//p1=head;//将头指针head所指地址赋给p1//for(i=1;i<=n;i++){printf("请输入第%d个人的密码:\n",i);scanf("%d",&j);//输入学生所带密码//p1->next=(linklist*)malloc(sizeof(linklist));//建立一个新的空间,并将它的地址赋给p1->next//p1=p1->next;p1->cipher=j;p1->num=i;//对结点的cipher和num成员赋值//p1->next=head->next;//构成单循环链表//}do{k=1;while(k!=m)//当k==m时一轮报数结束//{p1=p1->next;k++;}//报数过程中将指针p1指向下一位//p2=p1->next;p1->next=p2->next;//将报数为m的人得结点从链表中删去//printf("编号为%d的人出列,他的密码%d作为新的m值\n",p2->num,p2->cipher);//报数为m的人出列//m=p2->cipher;//将报数为m的人的密码作为新的m值//free(p2);//释放报m的人的结点//}while(p1->next!=p1);//当p1->next指向的地址是它自己的地址,所有报数结束//printf("编号为%d的人出列,至此所有人出列完毕\n",p1->num);//所有人出列//free(p1);//释放最后一个人的结点//free(head);//释放头结点//printf("程序结束\n");}五、实验结果测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5。

约瑟夫问题(算法与数据结构课设报告)

约瑟夫问题(算法与数据结构课设报告)

线性表的操作及其应用一、问题描述线性表、队列是一种常用的数据结构,有顺序和链式两种存储结构,在实际中应用十分广泛,而链表又分为单链表和循环链表,队列又分为链式队列和循环队列。

这些数据结构都可用来解决约瑟夫环问题。

约瑟夫环问题是算法设计中的一个经典问题,是顺序编号的一组n个人围坐一圈,从第1个人按一定方向顺序报数,在报到m时该人出列,然后按相同方法继续报数,直到所有人出列。

设计算法求约瑟夫环中人员的出列顺序。

二、基本要求1、选择合适的存储结构,建立线性表;2、利用顺序存储结构求解约瑟夫环问题;3、利用单链表和循环链表分别求解约瑟夫环问题;4、利用队列求解约瑟夫环问题。

三、测试数据约瑟夫环的测试数据为7,报数为1至3。

四、算法思想由于用到四种不同的存储结构,它们的算法思想依次是:1、首先建立一个顺序表模拟整个约瑟夫环,手动输入顺序表长(即参加约瑟夫循环的人数)和循环的次数和表元素。

用已经输出总人数和顺序表长作比较,作为外层循环条件。

并对每一个输出后的元素重新赋值以为标记。

对于每次循环,首先检查顺序表此次是不是我们设立的标记,如果不是则循环次数加1,当达到要求的循环次数时就将循环次数设置为0,输出该元素到屏幕并将总输出元素加1。

每次外循环我们都会移到表的下一个位置,作为新的判断条件,每次报到表尾的时候,我们都将重新设置到表尾,作为下次循环的表元素。

2、首先采用链式循环链表建立整个约瑟夫环,手动输入第一次的循环次数和每个人所持下一个循环次数。

设立判断指针指向表头,并将该指针是否为空作为外层循环条件。

做一个内层循环,将判断指针移动到循环要输出的数,并设立一个前指针指向该指针的前一个位置,输出该元素后,将循环次数重新赋值成该元素。

接着判断前指针和判断指针比较,如果相等说明整个表已经输出完毕,否则将删除该位置的元素。

3、用链式队列建立循环约瑟夫环,手动输入人数,第一次的循环次数和每个人所持下一个循环次数。

并将每一个元素依次入队列,根据第一次循环次数,建立一个for循环,每一次循环都出队列,如果达到要求的循环次数就输出,否则进队列,这样这个数字就出现在队尾。

约瑟夫环问题 实验报告完整版

约瑟夫环问题 实验报告完整版
struct Node
{
int data;//数据域
Node *next;//next指针指向下一个结点
};
3.算法设计
问题要求建立模型,确定存储结构,之后对任意n个人,密码为m,实现约瑟夫环问题,出圈的顺序可以依次输出,也可以用一个数组存储。
设计流程图如图1.1所示。
图1.1设计流程图
(1)创建循环链表
{
p=p->next;
}
q=p->next;
p->next=q->next;
p=p->next;
printf("第%3d个出圈的人是:%3d\n",i,q->value);
free(q);
}
scanf("\n");
p->next=NULL;
}
(3)主程序执行
主程序运行,调用函数,程序接受数据后,输出出圈列数。
}
(2)约瑟夫环报数的算法在运行为循环方式,报数者除非本身已经出去,否则继续顺序报数,其报数循环的代码为
void Joseph(NODE *p,int number,int n)
{
int i,j;
NODE *q=NULL;
for(i=1; i<=number; i++)
{
for(j=1; j<n-1; j++)
由于内容的要求以及问题的方便,用循环链表作为本次实验的抽象数据类型。申请一个结点作为第一个结点,之后调用creat_list函数将后续结点一次插入链接,构造为循环链表。
NODE *link(int number)
{
NODE *head=NULL,*p=NULL,*q=NULL;

约瑟夫环与八皇后问题--数据结构课程设计实验报告

约瑟夫环与八皇后问题--数据结构课程设计实验报告
目 一、 二、 三、 四、 五、 六、 七、
录 问题描述 1 问题分析 1 数据结构描述 算法设计 2 详细程序清单 程序运行结果 心得体会 12
1 4 11
一、 问题描述 1. 约瑟夫问题描述 编号为1,2... n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一 开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报 数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的 下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列 顺序。 2. 八皇后问题描述 在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相"冲"(在每一横 列竖列斜列只有一个皇后)。 3、界面设计模块问题描述 设计一个菜单式界面,让用户可以选择要解决的问题,同时可以退出程序。界面要 简洁明了,大方得体,便于用户的使用,同时,对于用户的错误选择可以进行有效的处 理。 二、 问题分析 在整个课程设计中,我主要负责的是约瑟夫问题中链表中的出列的操作算法的设计。 用循环单链表表示编号为1,2... n的n个人按顺时针方向围坐一圈,每人持有一个密码 (正整数)。一开始输入一个正整数作为报数的上限值turn,从第一个人开始按顺时针方 向自1开始顺序报数(即从第一个结点开始指针向后移动),报到turn-1时(即指针指向 turn-1个结点时)停止,他的下一位出列,将他的下一位密码作为新的turn值,从出列的 人的的顺时针方向上的下一个开始重新从1报数,如此下去,直至链表中只剩一位(即一 个结点)退出循环,并所有人的编号按出列顺序输出。在实现的过程中定义i表示报数的
int code; struct LNode *next; }node,*linklist; linklist creatstart(linklist L,int number) { int m,i; linklist s,p; s=L; for(i=1;i<=number;i++) { p=(linklist)malloc(sizeof(node)); if(!p) exit(0); p->data=i; printf("please input the code of number %d:",i); scanf("%d",&p->code); p->next=NULL; s->next=p; s=p; } s->next=L->next; return s; } void chulie(linklist L,int number) { int turn,i,j; linklist p,s; printf("please input the start code:"); scanf("%d",&turn); p=L; printf("the turn out of the circle is:"); for(i=1;i<=number-1;i++) { for(j=1;j<=turn-1;j++) p=p->next; printf("%d ",p->next->data); turn=p->next->code; s=p->next; p->next=s->next; free(s); } printf("%d ",p->next->data); printf("\n"); } void lianbiao() { int number; linklist L; L=(linklist)malloc(sizeof(node));

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

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

实验1约瑟夫环问题1.需求分析(1)输入的形式和输入值的范围:每一次输入的值为两个正整数,中间用逗号隔开。

若分别设为n,m,则输入格式为:“n,m”。

不对非法输入做处理,即假设输入都是合法的。

(2)输出的形式:输出格式1:在字符界面上输出这n个数的输出序列输出格式2:将这n个数的输出序列写入到文件中(3)程序所能达到的功能:对于输入的约瑟夫环长度n和间隔m,输出约瑟夫环的出列顺序。

(4)测试数据:包括正确的输入及其输出结果和含有错误的输入及其输出结果。

正确:输入:10,3输出:3 6 9 2 7 1 8 5 10 4输入:41,3输出:3 6 9 12 15 18 21 24 27 30 33 36 39 1 5 10 14 19 23 28 32 37 41 7 13 20 2634 40 8 17 29 38 11 25 2 22 4 35 16 31错误:输入:10 3输出:6 8 7 1 3 4 2 9 5 102.概要设计(1)抽象数据类型的定义:为实现上述程序的功能,可以用整数存储用户的输入。

并将用户输入的值存储于线性表中。

线性表ADT定义如下:ADT list数据对象:整形数据关系:线性关系,即<ai,ai+1>(0≤a<n)。

基本操作:bool remove(int &elem)//移除一个元素,被移除的元素赋给elem//如果操作成功,返回true,否则返回falsebool isEmpty()//判断数组的元素是否清空,空返回true,否则返回falsebool setPos(int place)//设置当前元素的位置,设置成功返回true,否则返回falseint getLength()//获取数组的实际长度(2)算法的基本思想:约瑟夫环问题中的数据是人所在的位置,而这种数据是存在“第一元素、最后元素”,并且存在“唯一的前驱和后继的”,符合线性表的特点。

约瑟夫环设计实验报告

约瑟夫环设计实验报告

一、实验目的1. 理解并掌握约瑟夫环问题的基本原理和解决方法。

2. 熟悉循环链表在数据结构中的应用,并能够运用其解决实际问题。

3. 提高编程能力和算法设计能力,培养逻辑思维和问题解决能力。

二、实验内容1. 实验背景约瑟夫环问题是一个经典的数学问题,描述了N个人围成一圈,按照一定的规则进行报数,最终确定出列顺序的过程。

该问题在计算机科学、通信等领域有广泛的应用。

2. 实验原理本实验采用循环链表作为数据结构来模拟约瑟夫环问题。

循环链表是一种线性表,其特点是最后一个节点的指针指向第一个节点,形成一个环。

在本实验中,我们将每个节点表示为一个人,节点的数据域存储该人的编号。

3. 实验步骤1. 初始化循环链表:首先创建一个循环链表,包含N个节点,节点编号依次为1, 2, ..., N。

2. 设置报数上限:从键盘输入一个正整数M,作为报数上限。

3. 模拟报数过程:a. 从链表头节点开始,按照顺时针方向进行报数。

b. 当报数达到M时,将当前节点出列,并将M的值设置为该节点的数据域。

c. 将指针指向下一个节点,继续进行报数。

d. 重复步骤b和c,直到链表中只剩下一个节点。

4. 输出出列顺序:按照出列的顺序,将每个节点的编号打印出来。

4. 实验代码```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int number;struct Node next;} Node;// 创建循环链表Node createList(int n) {Node head = NULL, tail = NULL, temp = NULL; for (int i = 1; i <= n; i++) {temp = (Node)malloc(sizeof(Node));temp->number = i;temp->next = NULL;if (head == NULL) {head = temp;tail = temp;} else {tail->next = temp;tail = temp;}}tail->next = head; // 形成循环链表return head;}// 打印出列顺序void printOrder(Node head) {Node temp = head;while (temp->next != temp) {printf("%d ", temp->number); temp = temp->next;}printf("%d\n", temp->number);}int main() {int n, m;printf("请输入人数: ");scanf("%d", &n);printf("请输入报数上限: ");scanf("%d", &m);Node head = createList(n);printOrder(head);// 释放内存Node temp;while (head->next != head) {temp = head;head = head->next;free(temp);}free(head);return 0;}```5. 实验结果与分析通过运行实验代码,可以得到约瑟夫环问题的出列顺序。

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