数据结构约瑟夫环的课程设计报告
约瑟夫环问题 实验报告
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; } 测试用例:
数据结构课程设计 约瑟夫环问题(报告+代码)
学院计算机与信息工程系数据结构课程设计设计题目:约瑟夫环问题专业班级学号姓名指导教师2010年12月20日约瑟夫环一.实验目的:本实验是设计一个可以解决约瑟夫环问题的程序。
此程序要求利用单向循环链表存储结构模拟此过程,按照出列的顺序印出个人的编号。
二.实验环境:VC2008.三.试验步骤:1.问题分析和任务定义本实验要求设计一个程序解决约瑟夫环问题,且要利用单向循环链表存储结构模拟此过程。
这就要求我们必须用链表结构而不能用像数组等其它结构。
首先输入的数据必须是整型且是整数,同样输出的也必须是整型且整数;其次也要备好测试数据(包括合法的输入数据和非法形式输入的数据)以此来检查程序是否符合要求;最后2.数据类型和系统设计链表存储结构的定义:typedef struct Node{}SeqList链表的建立:SeqList * Creat(int num){}链表的输出:void OutQueue(SeqList * tail, int num, int code){}3.详细设计:#include <stdio.h>#include <stdlib.h>typedef struct Node{int num;int code;struct Node * next;}SeqList;SeqList * Creat(int);void OutQueue(SeqList *, int , int );int main(){int n,m,i;printf( " 姓名:徐正杰学号:090502201:\n");printf("Input The Number of People, Frist Code:");{int num = 0,code = 0;scanf("%d%d",&num, &code);{SeqList * tail = NULL;tail=Creat(num);OutQueue(tail, num, code);}}return 0;}SeqList * Creat(int num){getchar();SeqList * tail = NULL;tail=(SeqList *)malloc(sizeof(SeqList));{int i = 1, code = 0;printf("Input Num.%d Code:", i);scanf("%d", &code);tail->num = i;tail->code = code;tail->next = tail;{SeqList * p = NULL;for(i = 2; i <= num; ++i){p = (SeqList *)malloc(sizeof(SeqList));if(p){printf("Input Num.%d Code:", i);scanf("%d", &code);p->num = i;p->code = code;p->next = tail->next;tail->next = p;tail = p;}else{perror("Out of menroy!");getchar();exit(1);}}}}return(tail);}void OutQueue(SeqList * tail, int num, int code) {printf("Out of Queue:");{SeqList * p;while(tail - tail->next){code=(code-1)%num+1;{int i;for(i = 1; i < code; ++i){tail = tail->next;}}p = tail->next;printf("%d,", p->num);tail->next = p->next;code = p->code;free(p);p = NULL;--num;}}printf("%d.",tail->num);free(tail);tail = NULL;}4.调试分析在本次试验调试中很不顺利。
实验报告——约瑟夫环
《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:约瑟夫环姓名:张光栋院系:计算机学院专业:网络工程年级: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.第一次写时,没有区分出只剩下的一个的情况,导致最终输出出现错误。
数据结构:约瑟夫环实验报告
数据结构实验报告题目:约瑟夫环姓名:学号:专业班级:指导教师:课题工作时间:一.需求分析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环-数据结构与算法课程设计报告
合肥学院计算机科学与技术系课程设计报告2009~2010学年第二学期课程数据结构与算法课程设计名称joseph环学生姓名朱玉庭学号0804012029专业班级08计本(2)指导教师王昆仑、张贯虹2010 年06月08号一、问题分析和任务定义:约瑟夫环是一个数学游戏,根据游戏内容的描述,能够很容易的看出,游戏中的玩家顺时针围坐一圈,能够很容易的发现,这跟本课上的单循环链表非常相似,所以可以通过单循环链表存储结构模拟此过程,当游戏中的玩家出列时,可以通过删除单循环链表中的结点来实现。
二、数据结构的选择和概要设计:选择带为指针的单循环链表来解决这个问题,先建立一个空链表,然后根据人数生成具有相应结点的单循环链表,知道密码后,通过循环来找到对应的结点,然后将该结点的编号输出,改变密码,最后删除结点,以此类推,知道编码全部输完,即可得到结果序列。
三、详细设计和编码:本题目是通过单循环链表存储结构来模拟此过程的,首先要先明确该单循环链表中结点的结构类型,定义如下:typedef struct Node{int key; //每个人持有的密码int num; //这个人的编号struct Node *next; //指向下一个结点}Link;当生成单循环链表时,就需要用到课本上创建单循环链表的有关内容了,可以先通过子函数Link *InitList()建立一个空链表,返回指针L,然后将返回的指针代入子函数Link *Creater(Link *L,int n)的形参中,对循环链表进行初始化,并且也返回一个指针,然后再将这个返回的指针代入到输出函数void Output(Link *L,int n,int m)的形参中,要想根据题目要求完成序列的输出,需要通过两个for循环来实现,第一个循环for(i=1;i<=n;i++) ,因为一个用n个人,所以结果要输出n个编号,这个循环每循环一次输出一个编号即printf("%d ",q->num),并将该编号下的密码赋值给m 即m=q->key,当循环完毕时正好将编号全部输出,第二个循环for(j=1;j<m;j++) p=p->next; q=p->next; 用以找到相应的结点,并用指针q指向它,当完成了编号的输出和密码的赋值后,删除q指向的结点,将两个循环适当结合,即可输出正确的结果序列,其中的人数n和初始密码在主函数中确定。
数据结构课程设计Joseph环
编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序。
I=*k;Operate(I,m,n);}
3、 函数的调用关系图为:
是 否
是否
测试
参加的人数为:3
起始报数上线值:2
输入第1个人的密码:4
输入第2个人的密码:5
输入第3个人的密码:6
输出结果为:
第1个出列的人的编号是:2 密码是:5
第2个出列的人的编号是:3 密码是:6
最后一个出局的人的编号是:1 密码是:4
inti=1,j;
LinkList J;
for(i=1; i<n; i++)
{
for(j=1; j<h; j++)
{
J=L;
L=L->next;
}//找出第m个元素
J->next=L->next;//将其删除
printf("第%d个出列的人的编号是:%d密码是:%d\n",i,L->data,L->password);
q=(*L);
q->next=NULL;
for(i=1;i<=z;i++)
{
p=(LinkList) malloc (sizeof(LNode));//建立一个linklist型的指针
q->next=p;
p->next=NULL;
约瑟夫环课程设计报告
课程设计报告课程设计名称:数据结构课程设计课程设计题目:约瑟夫环院(系):专业:班级:学号:姓名:指导教师:目录1 课程设计介绍 (1)1.1课程设计内容 (1)1.2课程设计要求 (1)2 课程设计原理 (2)2.1课设题目粗略分析 (2)2.2原理图介绍 (2)2.2.1 功能模块图(如图2.1) (2)2.2.2 流程图分析 (3)3 数据结构分析 (5)3.1存储结构 (5)3.2算法描述 (5)4 调试与分析 (6)4.1调试过程 (6)4.2程序执行过程 (6)参考文献 (8)附录(关键部分程序清单) (9)1 课程设计介绍1.1 课程设计内容编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
使用单循环链表作为存储结构分析:由题意可以将每个人看做链表上的一个节点,每个人持有的密码即为每个节点所存储的数据;相邻的人之间存在连结关系,即链表的两个相邻节点之间由指针来进行关联;最后一个人和第一个人也存在连结关系,即链表的末尾节点和头结点相连构成了单循环链表存储结构。
执行报数过程可以看做一个单独指针依次指向每一个节点,有人出列即删除掉链表中相应的节点。
1.2 课程设计要求1.参考相应的资料,独立完成课程设计任务。
2.交规范课程设计报告和软件代码。
2课程设计原理2.1 课设题目粗略分析根据课设题目要求,程序应该分为两大部分:1、单循环链表储存结构的建立:建立所需的单循环链表数据存储结构,对每个节点输入所需的密码、序号数据并通过指针连接成单循环链表。
2、实现约瑟夫环数据出列顺序的算法:依照题目要求按照报数上限对节点进行查找和删除操作,按顺序输出出列的节点序号,依照每次出列的节点存储的密码修改报数上限循环操作直到全部节点出列完毕程序运行结束。
数据结构课程设计约瑟夫环
《数据结构》课程设计报告书题目:约瑟夫环系别:计算机科学与应用学号:学生姓名:指导教师:完成日期: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个报数人的位置。
最后不断地从链表中删除链结点,直到链表为空。
(完整word版)约瑟夫环课程设计实验报告
《数据结构》课程设计报告课程名称:《数据结构》课程设计课程设计题目:joseph环姓名:院系:计算机学院专业:年级:学号:指导教师:2011年12月18日目录1 课程设计的目的 (2)2 需求分析 (2)3 课程设计报告内容 (3)1、概要设计 (3)2、详细设计 (3)3、调试分析 (x)4、用户手册 (x)5、测试结果 (6)6、程序清单 (7)4 小结 (10)1、课程设计的目的(1)熟练使用C++编写程序,解决实际问题;(2)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;(3)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;(4)提高综合运用所学的理论知识和方法独立分析和解决问题的能力;2、需求分析1、问题描述:编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。
设计一个程序来求出出列顺序。
2、要求:利用不带表头结点的单向循环链表存储结构模拟此过程,按照出列的顺序输出各个人的编号。
3、测试数据:m的初值为20,n=7 ,7个人的密码依次为3,1,7,2,4,7,4,首先m=6,则正确的输出是什么?输出形式:建立一个输出函数,将正确的输出序列3、课程设计报告内容概要设计:在理解了题目后,我先想到的是我们所学的单链表,利用单链表先建立循环链表进行存贮,建立完循环链表后,我将所要编写的函数分为了两块,一块是经过学过的单链表改编的循环链表的基本操作函数,还有一块是运行约瑟夫环的函数。
详细设计:我先建立一个结构体,与单链表一样,只是多了一个存密码的code域struct LinkNode{int data; //顺序int code; //密码LinkNode *next;};建立一个类LinkList ,包含的函数:LinkList(); //构造函数void Creat(const int ); //创建循环链表int Delete(LinkNode* ); //删除报到数的结点int Joseph(int ); // 约瑟夫环私有成员是LinkNode* head; //指向第一个结点的指针LinkNode* elem; // 同上int len; //长度我定义了一个elem指针是为了约瑟夫环里运行方便,elem只在约瑟夫环这个函数里用到,其他函数没有特别大的用处。
数据结构 约瑟夫环课程设计报告
课程设计报告一、需求分析1、本演示程序中,利用单向循环链表存储结构模拟约瑟夫问题的进行。
程序运行后,首先要求用户指定初始报数上限值,然后读取个人的密码。
可设n≤30。
此题所用的循环链表中不需要“头结点”,因此在程序设计中应注意空表和非空表的界限。
2、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令:相应的输入数据和运算结果显示在其后。
3、程序执行的命令包括:1)构造约瑟夫环;2)执行约瑟夫环,并输出出列人的序号以及相应的密码;3)结束。
4、测试数据1)m的初始值为20;2)n=7,7个人的密码依次为:3、1、7、2、4、8、4。
3)首先m值为6,正确的出列顺序应为6、1、4、7、2、3、5。
二、概要设计为实现上述程序功能,应以单向循环链表表示约瑟夫环。
为此,需要两个抽象数据类型:单向循环链表和约瑟夫环。
1)、单向循环链表的抽象数据类型定义为:ADT List{数据对象:D={ai|ai∈Elemset,i=1,2,…,n,n≥0}数据关系:R1={<a(i-1),ai>|a(i-1),ai∈D,i=2,…n}基本操作:InitList(&L)操作结果:构造一个空的链表L。
DestroyList(&L)初始条件:线性表L已存在。
操作结果:销毁线性表L。
ListLength(L)初始条件:线性表L已存在。
操作结果:返回L中数据元素个数。
GetElem(L,i,&e)初始条件:线性表L已存在,1≤i≤ListLength(L)。
操作结果:用e返回L中第i个数据元素的值。
ListInsert(&L,I,e)初始条件:线性表L已存在,1≤i≤ListLength(L)+1。
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1。
ListDelete(&L,i,&e)初始条件:线性表L已存在且非空,1≤i≤ListLength(L)。
数据结构课程设计报告(约瑟夫问题)
数据结构课程设计报告(约瑟夫问题)问题描述约瑟夫问题:编号为1-n的n个人围坐圆桌旁,从任一指定编号为k的人开始报数,报数为m的人离开圆桌,下一个人接着从n开始报数, 报数为m的人又离开圆桌,依此重复,直至所有人离开圆桌.编一程序,输出离开圆桌的人的编号序列.设计思想首先采单循环链表建立整个约瑟夫环,手动输入总人数(既链表的长度)、每个人的所持下一轮报数出对值和初始报数值。
node->num为人的编号,node->为此人所持的下一轮报数值。
建立单循环链表后,通过初始报数值找到出列的人,输出node->num的值,然后将该结点中的data值作为下一轮的报数值。
重复以上过程直至所有的人都出列,则程序结束。
主要算法do{k=1;while(k!=m)//当k=m时,结束第一轮报数{p1=p1->next;k++;}//报数中将指针指向下一位p2=p1->next;p1->next=p2->next;//把报数为m的人的结点从链表中删除printf("编号为%d的人出列,他的key%d作为新的m值/n",p2->num,p2->data);//m=p2->data;//报数为m的人的密码作为下一轮新的m值free(p2);//释放报m的人的结点}while(p1->next!=p1);//当p1->指向自己时,报数结束的值加一,当k=m时,此时p1指向人出列,p2指向该结点的上一结点,k为计数器,指针每移动一次,k让上一结点的next指向该结点的下一结点,然后删除该结点。
P1指向该结点下一结点,令k=1,再开始下一轮报数。
等到所有人出列后,循环结束。
for(i=1;i<=n;i++){printf("请输入%d号同学的key",i);scanf("%d",&j);//输入学生所带有的密码p1->next =(listnode*)malloc(sizeof(listnode));//建立一个空间p1=p1->next ;p1->data=j;p1->num=i;//对结点的num和data成员赋值p1->next=head->next; }定义指针p1,然后建立一个新结点并将p1->next指向他,再将地址赋给p1,最后将head->next赋给p1->next,构成了循环单链表,然后让所有人键入链表并给num和data成员赋值。
数据结构课程设计报告-约瑟夫环问题
华北科技学院课程设计说明书班级: 姓名:____设计题目: 约瑟夫环设计时间:____2011-2-28 至__2011-3-11指导教师:评语:_________________________________ _________________________________________ _________________________________________ _________________________________________ _________________________________________ 评阅成绩:____评阅教师:_____一、设计题目与要求设计题目:约瑟夫环问题描述:编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
基本要求:1、利用单循环链表作为存储结构模拟此过程;2、键盘输入总人数、初始报数上限值m及各人密码;3、显示游戏中队形及各人密码变化过程;4、按照出列顺序输出各人的编号。
二、概要设计实验设计思路:1.以无头结点的单循环链表为存储结构模拟此过程。
2.键盘录入各各同学所持密码,存储在一维数组a[]中。
3.单循环链表初始化时,将密码和编号存入结构体中。
4.进行单链表删除操作,直到链表为空,输出的编号存入数组b[]中5.依次输出b[]中的元素。
程序结构:本程序是单文件程序,构成的函数有LinkedList LinkedListInit(int n,int a[]) 初始化循环单链表void LinkedListTraverse(LinkedList L) 遍历单链表void Play(LinkedList L,int m,int b[],int n) 单循环链表的删除void main() 主函数,输出出队序列其中,void Play()是最主要的函数,初始化单链表后,开始执行该函数,指针按给定的密码值m依次后移m次删除定位后的结点,输出编号,同时获得新的m 值,继续循环,直到该链表为空。
约瑟夫环课程设计报告
C++ 课程设计报告课 题: 约瑟夫环 专业班级: 学 号: 姓 名: 指导教师:目 录评阅意见:评定成绩:指导老师签名:年 月 日1 课程设计的目的和意义 (2)2 需求分析 (3)3 系统(项目)设计 (4)(包括总体设计和详细设计) (4)一、设计思路及方案 (4)二、模块的设计及介绍 (4)(2)创建单循环链表函数流程图 (6)(3)删除结点函数(出队函数)程序流程图 (7)4 系统实现 (8)5 系统调试 (11)参考文献 (15)附录源程序 (16)1 课程设计的目的和意义数据结构是研究数据元素之间的逻辑关系的一门课程,以及数据元素及其关系在计算机中的存储表示和对这些数据所施加的运算。
该课程设计的目的是通过课程设计的综合训练,培养分析和编程等实际动手能力,系统掌握数据结构这门课程的主要内容。
本次课程设计的内容是用单循环链表模拟约瑟夫环游戏,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。
通过这个设计实例,了解单链表和单循环链表的相同与不同之处,进一步加深对链表结构类型及链表操作的理解。
通过该课程设计,能运用所学知识,能上机解决一些实际问题,了解并初步掌握设计、实现较大程序的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。
2 需求分析该程序所做的工作是约瑟夫环游戏,有以下内容和要求:1.本程序设计中,从键盘输入约瑟夫环游戏的总人数n和初始的报数上限m,然后给每个人输入所持有的密码key。
用单循环链表模拟约瑟夫环,从队头开始从1报数,报到m的人出列,再把此人的密码赋给m,继续下一轮的报数,直到所有的人出列。
2.演示程序以用户和计算机对话方式进行,根据提示信息由用户从键盘输入数据,以“回车符“为结束标志,运行后输出的结果是约瑟夫环的相关信息和经过报数后出队的人的序列号及相关信息。
约瑟夫环问题 实验报告完整版
对任意 n 个人,密码为 m,实现约瑟夫环问题。 出圈的顺序可以依次输出,也可以用一个数组存储。
(3)思考: 采用顺序存储结构如何实现约瑟夫环问题
如果每个人持有的密码不同,应如何实现约瑟夫环问题
2.数据结构设计
由于约瑟夫环问题本身具有循环性质,考虑采用循环链表,为了统一对表中 任意结点的操作,循环链表不带头结点。将循环链表的结点定义为如下结构类型:
实验报告
实验课名称:数据结构实验一
实验名称:约瑟夫环问题
班级 000
学号 000
姓 名 神 刀 公 时间 子
1.问题描述
约瑟夫环问题
(1)问题描述 设有编号为 1,2,…,n 的 n(n>0)个人围成一个圈,每个人持有一个密码 m。 从第一个人开始报数,报到 m 时停止报数,报 m 的人出圈,再从他的下一个人 起重新报数,报到 m 时停止报数,报 m 的出圈,……,如此下去,直到所有人全 部出圈为止。当任意给定 n 和 m 后,设计算法求 n 个人出圈的次序。 (2)基本要求
4.界面设计
程序无需复杂的界面设计,包含输入提示功能和输出提示功能。
5.运行测试与分析
(1)输出提示 ,如图所示。
(2)根据提示,输入圈内人数 n 和每个人持有的密码 m 如图所示。
(3)输出结果如图所示
分析 6.实验收获及思考
通过该实验,我进一步增强了对于链表的理解,也对链表的操作和实现更为熟 悉,熟练掌握了如何实现置空表、求表的长度、取结点、定位运算、插入运算、 删除运算、建立不带头结点的单链表(头插入法建表)、建立带头结点的单链表 (尾插入法建表),输出带头结点的单链表等操作。同时,锻炼了实际操作时的 动手能力。
struct Node {
约瑟夫环设计实验报告
一、实验目的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.实验目的本实验的目的是分析约瑟夫问题,并设计合适的数据结构解决该问题。
2.实验背景约瑟夫问题,又称为约瑟夫环,是一个经典的数学问题。
问题描述如下:有n个人围成一圈,从第一个人开始报数,数到第m个人时将其杀死,然后从下一个人开始重新报数,数到第m个人又将其杀死,如此循环进行,直到所有人都被杀死为止。
求出最后一个被杀的人在初始序列中的编号。
3.实验设计为了解决约瑟夫问题,我们需要设计合适的数据结构来表示这个过程。
以下为实验所采用的数据结构:3.1 线性表由于约瑟夫问题是围成一圈的,因此我们选择使用循环链表来表示人围成的圈。
每个节点代表一个人,包含一个成员变量用于存储人的编号。
3.2 算法采用如下算法来解决约瑟夫问题:1.创建一个循环链表,将n个人的编号分别存入节点中。
2.初始化一个指针p指向链表的第一个节点。
3.从第一个人开始报数,每报到第m个人,将该节点从链表中删除。
4.如果链表中只剩下一个节点,此时的节点即为最后一个被杀的人,输出其编号。
4.实验步骤4.1 数据结构设计根据实验设计中的描述,我们编写了一个含有循环链表和节点的数据结构。
```cppstruct ListNode {int number;ListNode next;};```4.2 实现约瑟夫问题算法根据实验设计中的算法描述,我们编写了解决约瑟夫问题的函数。
```cppint josephusProblem(int n, int m) {// 创建循环链表// 初始化指针p// 开始报数并删除节点// 返回最后被杀的人的编号}```4.3 测试与分析我们通过输入不同的n和m值,测试了约瑟夫问题的解决函数,并对实验结果进行了分析。
5.实验结果经过测试,我们得到了约瑟夫问题的解。
6.实验总结通过本实验,我们深入了解了约瑟夫问题,并成功设计了合适的数据结构和算法解决了该问题。
附件本文档无附件。
法律名词及注释1.约瑟夫问题:亦称为约瑟夫环问题,是一个数学难题,起源于古代历史记载,已有几个世纪的历史。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
武汉工业学院数学与计算机学院
数据结构课程设计
设计题目:约瑟夫环
专业大类计算机
班级计算机6班
学号 100702129
姓名王元
指导教师李禹生
2011年9月3 日
一.选题背景:
题目:约瑟夫环
问题描述:
编号为1,2,…..,n的n个人按顺时针方向围坐圈,每个人持有一个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新重新从1报数,如此下去,直至所有人全部出列为止。
基本要求:
⑴建立模型,确定存储结构;
⑵对任意 n个人,密码为 m,实现约瑟夫环问题;
⑶出圈的顺序可以依次输出,也可以用一个数组存储。
设计指导思想:
首先,设计实现约瑟夫环问题的存储结构。
由于约瑟夫环问题本身具有循环性质,考虑采用循环链表,为了统一对表中任意结点的操作,循环链表不带头结点。
其次,建立一个不带头结点的循环链表并由头指针 first 指示。
最后,设计约瑟夫环问题的算法。
下面给出伪代码描述,操作示意图如图 2-1 所示。
二.方案论证:
本方案通过建立单循环链表模拟了约瑟夫问题;首先,建立一个结构体node,然后给他开辟一个储存空间;利用头指针head标记链表,利用尾指针向后移将建立的结点连接成我们需要的单循环链表,
过程如下:
约瑟夫问题中的人数个数即为链表的长度,链表中node->num 编号n,node->data为每个人的密码。
建立单循环链表后,通过初始报数上限找到出列的结点,输出该结点的node->num值,将该结点中的data中数作为新密码开始下一个步的开始,将该结点从链表中删除,并释放该结点的空间。
重复此过程,直到剩下最后一个结点,就直接将该结点中的num值输出,删除该结点,并释放该结点的空间。
输出的num值即为约瑟夫中人的编号。
三.过程论述:
typedef struct node
{
int data;
int num;
struct node *next;
}listnode;
定义一个结构体用来储存学生的编号和所携带的密码
for(i=1;i<=n;i++)
{
printf("输入第%d号同学的密码:",i);
scanf("%d",&j);//输入学生所带密码
p1->next=(listnode*)malloc(sizeof(listnode));//建立一个新的空间,并将它的地址赋给p1->next
p1=p1->next;
p1->data=j;
p1->num=i;//对结点的num和data成员赋值
p1->next=head->next;//构成单循环链表
}
定义指针p1,然后建立一个新结点并将p1->next指向它的地址,然后将这个地址赋给p1,最后将head->next赋给p1->next,构成一个单循环链表,并不断在尾部插入新的结点,直至所有人都进入循环链表中,而且在循环的过程中给结点的num和data成员赋值
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->data);//报数为m的人出列
m=p2->data;//报数为m的人的密码作为新的m值
free(p2);//释放报m的人的结点
}while(p1->next!=p1);//当p1->next指向的地址是它自己的地址,所有报数结束
定义指针p1用以循环链表,定义变量k计数,指针p1每移动一次,k加1,直到k==m时,输出指针p1所指向的节点序号,也就是令这个“人”出列,p2指向该节点上一节点,令上一节点next域指向该节点下一节点,然后删除该节点,令头节点p1指向该节点下一节点作为再次报数初始“人”,再令k归1,继续循环。
知道p1->next= =p1时,表示所有“人”出列完毕,删除最后的节点后跳出循环
四.结果分析:
测试数据:
n=4, 4个人的密码依次为4, 3,8, 6, 首先m=6
输出结果:
测试数据:
n=7,7个人的密码依次为3,1,7,2,48,4,首先m=20
输出结果:
五.课程设计总结:
为期一周的课程设计快结束了,通过这次数据结构课程设计,我感受最深的就是对于循环链表的使用,可以说对循环链表有了比以前更进一步的认识,以前只是一知半解的,如果只给个题目自己根本不能把程序完整地编写出来,所以这次课程设计最大的收获就在于对循环链表有了一定的理解,包括其中的一系列操作,如建立一个循环链表,删除链表中的一个结点,增加一个结点等。
在这次课程设计过程中需要我们一边设计一边探索,这这个过程当中我发现自己在数据结构方面知识掌握不够深入,对一些基本概念不能很好的理解,对一些数据结构不能够熟练的进行上机实现,这是自己比较薄弱的。
学好基础知识是理论付诸实践的前提,这样理论和实践才能充分地结合起来。
在以后的学习中,我还要努力改正,充分利用上机实验的机会提高自己。
在程序的输入的时候,因为自己对键盘的不熟练,代码又很多很繁琐,常常会产生放弃的念头,从中我也感受到只有坚持到底,胜利才会出现。
在调试程序的时候我也有所体会,虽然约瑟夫环问题不是很难,但调试的时候还是会出现很多错误,因此我们不能认为容易就不认真对待。
在以后的学习中,要能不断发现问题,提出问题,解决问题,从
不足之处出发,在不断学习中提高自己。
六.附录:完整程序代码
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
int num;
struct node *next;
}listnode;
typedef listnode *linklist;
void main()
{
int n,m,i,j,k;
linklist head=(listnode*)malloc(sizeof(listnode));//开辟一个空间,并将它的起始地址赋给头指针head
listnode *p1,*p2;
printf("输入总人数:");
scanf("%d",&n); //输入总人数
printf("输入报数上限m:");
scanf("%d",&m);//输入初始报数上限
if(m<=0)printf("输入错误");//初始报数上限必须大于0
p1=head;//将头指针head所指地址赋给p1
for(i=1;i<=n;i++)
{
printf("输入第%d号同学的密码:",i);
scanf("%d",&j);//输入学生所带密码
p1->next=(listnode*)malloc(sizeof(listnode));//建立一个新的空间,并将它的地址赋给p1->next
p1=p1->next;
p1->data=j;
p1->num=i;//对结点的num和data成员赋值
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->data);//报数为m的人出列
m=p2->data;//报数为m的人的密码作为新的m值
free(p2);//释放报m的人的结点
}while(p1->next!=p1);//当p1->next指向的地址是它自己的地址,所有报数结束
printf("编号为%d的人出列,至此所有人出列完毕
\n",p1->num);//至此所有人出列完毕
free(p1);//释放最后一个人的结点
free(head);//释放头结点
printf("程序结束\n");
}。