北邮数据结构实验一约瑟夫问题实验报告(递归做法)

合集下载

约瑟夫环问题 实验报告

约瑟夫环问题 实验报告

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.调试分析在本次试验调试中很不顺利。

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

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

数据结构实验报告题目:约瑟夫环姓名:学号:专业班级:指导教师:课题工作时间:一.需求分析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()是最主要的函数,分别执行两种算法,并在执行的同时按照出列顺序输出元素信息(编号,密码),并在结尾输出两种算法执行所用的时间长短。

北邮数据结构实验-约瑟夫环

北邮数据结构实验-约瑟夫环

北邮数据结构实验-约瑟夫环数据结构实验报告实验名称:实验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个人。

数据结构实验一约瑟夫(Joseph)问题

数据结构实验一约瑟夫(Joseph)问题

华北#########学院数据结构实验报告2011~2012学年第二学期级计算机专业班级:学号:姓名:实验一线性表及其应用一、实验题目:线性表及其应用——约瑟夫环二、实验内容:1.设带头结点的单链表ha和hb中结点数据域值按从小到大顺序排列,且各自链表内无重复的结点,要求:(1)建立两个按升序排列的单链表ha和hb。

(2)将单链表ha合并到单链表hb中,且归并后的hb链表内无重复的结点,结点值仍保持从小到大顺序排列。

(3)输出合并后单链表hb中每个结点的数据域值。

代码:实验结果:struct Node{ int data;Node* next; };typedef Node Slink;void create(Slink* h);void show(Slink* h);void merge(Slink* ha,Slink* hb);#include<iostream.h>void main(){cout<<"创建链表ha"<<endl;Slink ha; ha.next =NULL;create(&ha);cout<<"链表ha的节点排列"<<endl;show(&ha);cout<<endl;cout<<"创建链表hb"<<endl;Slink hb; hb.next =NULL;create(&hb);cout<<"链表hb的节点排列"<<endl;show(&hb);cout<<endl;cout<<"合并后链表hb的节点排列"<<endl;merge(&ha,&hb);show(&hb);}void create(Slink* h){if(!h) return;int n=0;//节点总数int j=0;//累计创建结点个数cout<<"请输入创建节点的个数"<<endl;cin>>n;Node* F=h;//F始终指向tou节点Node* pre=h;//pre始终指向要插入位置的前一个节点while(j<n){Node* p=new Node;cout<<"请输入节点的数据"<<endl;cin>>p->data;//链表为空时if(!F->next ){ F->next =p;p->next =NULL;j++;continue;}//链表不空时while(pre->next ){ if(p->data <pre->next ->data ){ p->next =pre->next ;pre->next =p;pre=h;j++;break;}else if (p->data ==pre->next ->data){ cout<<"该值已存在,请重新输入"<<endl;break;}pre=pre->next ;}if(!pre->next ){ pre->next =p;p->next =NULL;j++;}}}void merge(Slink* ha,Slink* hb){ //p遍历ha,q遍历hbNode * p=ha->next ;Node * q=hb->next ;//pw始终指向新生成链表的最后一个结点Node * pw=hb;while(p&&q){ if((p->data)<(q->data)){ pw->next=p;p=p->next;pw=pw->next;continue;}if((p->data)>(q->data)){ pw->next=q;q=q->next;pw=pw->next;continue;}if((p->data)==(q->data)){ pw->next=q;p=p->next;q=q->next;pw=pw->next;continue;}}while(p){ pw->next=p;p=p->next;pw=pw->next;}while(q){ pw->next=q;q=q->next;pw=pw->next;}pw->next=NULL;}void show(Slink* h){Node* p=h->next ;while(p ){ cout<<p->data <<" ";p=p->next ;}cout<<endl;}2.约瑟夫(Joseph)问题。

数据结构实验报告—约瑟夫问题求解

数据结构实验报告—约瑟夫问题求解

《计算机软件技术基础》实验报告I—数据结构实验一、约瑟夫斯问题求解一、问题描述1.实验题目:编号1,2,....,n的n个人顺时针围坐一圈,每人持有一个密码(正整数)。

开始选择一个正整数作为报数上限m,从第一个人开始顺时针自1报数,报到m的人出列,将他的密码作为新的m值,从他在顺时针方向下一个人开始重新从1报数,直至所有人全部出列。

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

3.测试数据:n=7,7个人的密码依次为:3,1,7,2,4,8,4.m初值为6(正确的出列顺序应为6,1,4,77,2,3)。

二、需求分析1.本程序所能达到的基本可能:该程序基于循环链表来解决约瑟夫问题。

用循环链表来模拟n个人围坐一圈,用链表中的每一个结点代表一个人和他所代表的密码。

在输入初始密码后m,对该链表进行遍历,直到第m个结点,令该结点的密码值作为新的密码值,后删除该结点。

重复上述过程,直至所有的结点被释放空间出列。

2.输入输出形式及输入值范围:程序运行后提示用户输入总人数。

输入人数n后,程序显示提示信息,提示用户输入第i个人的密码,在输入达到预定次数后自动跳出该循环。

程序显示提示信息,提示用户输入初始密码,密码须为正整数且不大于总人数。

3.输出形式提示用户输入初始密码,程序执行结束后会输出相应的出列结点的顺序,亦即其编号。

用户输入完毕后,程序自动运行输出运行结果。

4.测试数据要求:测试数据n=7,7个人的密码依次为:3,1,7,2,4,8,4。

m初值为6(正确的出列顺序应为6,1,4,7,2,3,5)。

三、概要设计为了实现上述功能,应用循环链表来模拟该过程,用结构体来存放其相应的编号和密码信息,因此需要循环链表结构体这个抽象数据类型。

1.循环链表结构体抽象数据类型定义:ADT Node{数据对象:D={ai,bi,ci|ai∈int, bi∈int,ci∈(Node*),i =1,2...,n,n ≥0}:数据关系:R=∅基本操作:CreatList(int n) //构建循环单链表;Order(int m,node *l) //输出函数,输出出列顺序并删除链表中的结点;}ADT node;2. ADT的C语言形式说明:typedef struct Node{int num; //结点的数据域,存放编号;int word; //结点的数据域,存放密码;struct Node *next; //结点的指针域,存放指向下一结点的指针;}Node;Node *CreatList( ) //建立循环单项链表;void Order(Node *h) //输出出列顺序并删除结点;3. 主程序流程及其模块调用关系:1).主程序流程:先提示用户输入相关数据:总人数,运行循环链表结构体模块,输入每个人持有的密码值,创建出新链表,运行输出函数模块,再输入初始密码m值,输出出列序列。

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

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

实验报告实验一线性表的基本操作及其应用一、实验目的1、复习C语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。

二、实验内容本次实验提供2个题目,如果实现第一个题目有困难,可做第二个题目题目一:约瑟夫环[问题描述]约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人可有代表本人的序号。

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

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

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

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

[测试数据]由学生任意指定。

如:m的初值为5;n的值为7;序号:3,1,7,2,4,8,4;(报告上要求写出多批数据测试结果)[实现提示]程序运行后首先要求用户输入初始报数m,人数n,(设n≤30)。

然后输入各人的序号。

[选作内容]向上述程序中添加在顺序结构上实现的部分实验题目一:约瑟夫环一.需求分析1.利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。

2.演示程序以用户和计算机的对话方式执行,即在计算机上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据(滤去输入中的非法字符)和运算结构显示在其后。

3.程序执行的命令包括:1)输入报数上限值;2)输入人数以及所持密码;3)输出出列顺序;4)结束2)测试数据4.由学生任意指定。

如:m的初值为5;n的值为7;序号:3,1,7,2,4,8,4;二.概要设计为实现上述程序功能,需建立单向循环链表以存储此结构。

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

1.链表结点的抽象数据类型定义为:ADT2.本程序包含三个模块:3)主程序模块;4)循环链表的创建模块——实现创建循环链表;5)出列操作的模块——实现最终的出列操作;各模块之间的调用关系如下:出列操作的模块<——主程序模块——>循环链表的创建模块三.详细设计1.元素类型,结点类型和指针类型struct Lnode{int password;struct Lnode *next;};typedef struct Lnode *LinkList;2. 子函数1,创建循环链表int Creatlist_L(LinkList &head,int n)程序的实现:int Creatlist_L(LinkList &head,int n){//利用引用调用得到头指针head;int i;LinkList p,q;printf("请依次输入各位密码:");for(i=1;i<=n;i++){if(i==1){//申请一个空间,将头指针head和指针p均指向第一个结点;head=p=(LinkList)malloc(sizeof(struct Lnode));if(p==0) return 0; //分配存储空间失败}else{q=(LinkList)malloc(sizeof(struct Lnode));if(q==0) return 0;p->next=q;//通过next将下一个结点和前一个结点连起来;p=q;}scanf("%d",&(p->password));//一次输入对应的密码;}p->next=head;//构成循环链表,并返回链表的头指针return 0;}void DeleteNode(LinkList head,int m,int n){LinkList p,q;int j,i;p=head;for(j=1;j<n;j++){//先出列前n-1个人,并依次释放其结点的空间;for(i=1;i<m;i++,p=p->next);//寻找第m个人;printf("%d ",p->password);p->password=p->next->password;//将后一个结点的数据全部赋值于当前p所指的结点q=p->next;p->next=p->next->next;//p指向其下一个的下个一结点,重新开始寻找;free(q);}printf("%d",p->password);//最后一个人出列,并释放其结点所占空间;free(p);} }scanf("%d",&(p->password));//一次输入对应的密码;}p->next=head;//构成循环链表,并返回链表的头指针return 0;}3.主函数的实现,对两个子函数的调用void main(){int n,m;LinkList List;printf("输入人数:");scanf("%d",&n);printf("输入值m:");scanf("%d",&m);Creatlist_L(List,n);DeleteNode(List,m,n);printf("\n");}4.函数的调用关系图反映了演示程序的层次结构:main——>Creatlist;main——>DeleteNode;四调试分析1.由于对引用调用理解的不透侧,导致刚开始修改了很长时间。

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

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

数据结构实验报告约瑟夫环约瑟夫环是一种经典的数学问题,它源于古代传说中的故事。

根据传说,约瑟夫是一位犹太历史学家,他和他的朋友们被罗马军队包围在一个洞穴里。

为了避免被俘虏,他们决定自杀,但是他们决定以一个特殊的方式来做。

他们围成一个环,从一个人开始,每隔一个人就杀死一个,直到只剩下一个人。

约瑟夫是最后一个幸存者。

这个问题可以用数据结构来解决,其中最常用的方法是使用循环链表。

循环链表是一种特殊的链表,它的最后一个节点指向第一个节点,形成一个环。

在解决约瑟夫环问题时,我们可以使用循环链表来模拟这个环。

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

然后,我们需要设置一个计数器,用来记录当前的位置。

接下来,我们需要遍历链表,每次遍历到计数器所指向的位置时,将该节点从链表中删除,并将计数器加一。

当计数器的值等于要删除的位置时,我们就将该节点删除,并将计数器重置为1。

重复这个过程,直到链表中只剩下一个节点为止。

通过使用循环链表,我们可以很方便地解决约瑟夫环问题。

这种方法的时间复杂度为O(n*m),其中n表示初始链表的长度,m表示要删除的位置。

由于每次删除一个节点后,链表的长度会减少,所以实际上的时间复杂度会小于O(n*m)。

除了使用循环链表,还可以使用数组来解决约瑟夫环问题。

我们可以创建一个长度为n的数组,然后将所有的人依次添加到数组中。

接下来,我们需要设置一个计数器,用来记录当前的位置。

然后,我们需要遍历数组,每次遍历到计数器所指向的位置时,将该人从数组中删除,并将计数器加一。

当计数器的值等于要删除的位置时,我们就将该人删除,并将计数器重置为1。

重复这个过程,直到数组中只剩下一个人为止。

与循环链表相比,使用数组解决约瑟夫环问题的方法更加简单。

但是,数组的长度是固定的,所以如果要解决的问题规模很大,可能会导致内存的浪费。

此外,数组的删除操作需要移动其他元素,所以时间复杂度较高。

综上所述,约瑟夫环问题是一个经典的数学问题,可以通过使用循环链表或数组来解决。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

北邮数据结构实验一_约瑟夫问题_实验报告

北邮数据结构实验一_约瑟夫问题_实验报告

北京邮电大学电信工程学院数据结构实验报告实验名称:实验一——线性表学生姓名:班级:班内序号:学号:日期:1.实验要求实验目的熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法学习指针、模板类、异常处理的使用掌握线性表的操作的实现方法学习使用线性表解决实际问题的能力实验内容利用循环链表实现约瑟夫问题的求解。

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

从序号为1的人开始报数,顺时针数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规则重复下去,直到所有人全部出列。

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

2. 程序分析2.1 存储结构采用单循环链表实现约瑟夫问题的求解单循环链表存储结构示意图2.2 关键算法分析基本思想:首先,应该确定构造链表时所用的插入方法。

当数到m的那个人就出列,也即删除这个节点,同时建立这个节点的前节点与后节点的联系。

由于是循环计数,所以才采用循环列表方式。

第1页其次还要考虑输入值异常的情况。

之后,就是关于出列节点的逻辑判断。

依次找到待删结点的直接前驱,便于删除结点后修改它的直接后继,如此循环直到最后一个人出列。

关键算法:1.最后一个数据指向头指针,形成循环链表head=new Node; //确定头结点p=head;for(i=1;i<=n-1;i++) //赋初值{p->data=i;p->next=new Node; //为下一个新建内存p=p->next;}p->data=n; //最后一个单独处理p->next=head; //指向头,形成循环链表p=head;2.输入值异常的情况cout<<"请输入环内总人数n:";cin>>n;if (n<1) //考虑n输入错误的情况{cout<<"n值输入错误"<<endl;}cout<<"请输入起始人号码:";cin>>k;if (k<1||k>n) //考虑k输入异常的情况{cout<<"k值输入错误"<<endl;}cout<<"请输入m值:";cin>>m;if (m<1) //考虑m输入异常的情况{cout<<"m值输入错误"<<endl;}3.在约瑟夫环中实现逐个出环并找出最后一个出环的序号while(p!=p->next){for(i=1;i<m-1;i++) //查找q的节点p=p->next;q=p->next;cout<<"第"<<s<<"个出环的人编号是:"<<q->data<<endl;p->next=q->next;北京邮电大学信息与通信工程学院p=p->next;delete q; //释放q的空间s++;}cout<<"最后环内留下的人编号是:"<<p->data<<endl;delete p;算法步骤:①从第一个结点开始,查找第i-1个元素,设为p指向该结点;②设q指向第i个元素:q = p->next;,输出q元素的数据;③摘链,即将q元素从链表中摘除:p->next = q->next;p=p->next;delete q;3. 程序运行结果1、测试主函数流程:流程图如图所示第3页2、程序运行结果3、输入错误运行结果4. 总结在调试程序过程中,虽然没有编译错误,但是运行结果总是和准确值差1,最后发现是把i=1写成i=0,才造成的错误,改过之后就没有问题了。

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

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

数据结构实验报告
课程名称数据结构
实验名称数据结构试验
专业班级
姓名
学号
实验日期第 11 周星期日节
2012—2013学年度第一学期
再输入间隔数4后回车:输入起始位置
输入数据1 2 3 4 5 6 7 8,回车:
筛选后的结果就如屏幕所示
若中途输入的起始位置为9,回车,会提示如下
八、实验小结:
你在编程过程中花时多少?
总共用来将近2小时
多少时间在纸上设计?
大约有半个小时在纸上设计
多少时间上机输入和调试?
45分钟左右
多少时间在思考问题?
剩下的所有时间在思考这些问题
遇到了哪些难题?
如何实现循环的跳出,还有在轮到输出的数据释放后,该如何调整指针来正常继续运行成程序
你是怎么克服的?
我是通过画过几个数组,然后从手工图中得到了思路
你的收获有哪些?
通过这次试验让我对循环结构有了另外的感悟,还有数组的操作逻辑的看法有了很大改变。

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

约瑟夫环问题 实验报告完整版
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;

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

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

约瑟夫问题数据结构实验报告正文:⒈引言本实验报告旨在探讨约瑟夫问题及其相关数据结构的实现。

约瑟夫问题是一个经典的数学问题,涉及到环形数据结构和循环删除等操作。

通过本次实验,我们将实现约瑟夫问题的求解算法,并对其进行性能分析。

⒉算法描述⑴问题描述约瑟夫问题描述如下:有n个人围成一圈,从某个人开始依次报数,报到m的人出圈,然后从出圈的下一个人开始重新报数,如此循环,直到剩下最后一个人。

需要实现一个算法解决以下问题:(1)给定n和m,求出最后剩下的人的编号。

(2)给定n和m,按顺序输出出圈的人的编号。

⑵算法思路本实验将使用环形链表作为数据结构存储人员编号。

首先,创建一个含有n个节点的环形链表,每个节点表示一个人的编号。

然后,按照报数规则不断遍历链表,当报数等于m时,删除当前节点,并将游标指向下一个节点。

重复此过程,直到只剩下一个节点。

最后剩下的节点即为问题的解。

⒊算法设计⑴定义数据结构为了实现约瑟夫问题的求解,我们需要设计以下数据结构:(1)Person:表示每个人的节点,包含编号和指向下一个节点的指针。

(2)CircularLinkedList:表示环形链表,包含人员总数,当前游标位置和指向第一个节点的指针。

⑵算法实现(1)创建环形链表根据输入的人员总数n,创建一个含有n个节点的环形链表,每个节点表示一个人。

初始化时,节点的编号为从1到n,指向下一个节点的指针为空。

(2)解决约瑟夫问题通过循环遍历环形链表,按照报数规则逐个删除节点,直到只剩下一个节点为止。

具体步骤如下:①初始化报数计数器count=1,游标指向链表的第一个节点。

②从游标指向的节点开始,依次报数,每报数一次,count加1.③当count等于m时,删除当前节点,并将游标指向下一个节点。

④重复步骤②和③,直到只剩下一个节点。

(3)输出解决结果根据求解约瑟夫问题的要求,输出最后剩下的人的编号或按顺序输出出圈人的编号。

⒋性能分析本算法的时间复杂度为O(nm),其中n表示人员总数,m表示报数的步长。

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

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

实验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)算法的基本思想:约瑟夫环问题中的数据是人所在的位置,而这种数据是存在“第一元素、最后元素”,并且存在“唯一的前驱和后继的”,符合线性表的特点。

最新实验一约瑟夫问题实验报告

最新实验一约瑟夫问题实验报告

最新实验一约瑟夫问题实验报告实验目的:探究约瑟夫问题(Josephus Problem)的数学规律及其在不同参数下的表现,验证相关算法的效率和准确性。

实验背景:约瑟夫问题是一个著名的理论问题,源自于罗马时代的一个传说。

问题可以描述为:n个人围成一圈,从第一个人开始报数,每数到第m个人,该人出圈,然后从下一个人重新开始报数,如此循环,直到所有人出圈。

本实验旨在通过编程模拟这一过程,并分析结果。

实验方法:1. 采用编程语言(如Python)编写约瑟夫问题的模拟程序。

2. 设定不同的n和m值,运行程序,记录每个人的出圈顺序及最后剩下的人的位置。

3. 分析不同n和m值下的出圈顺序规律。

4. 对比不同算法(如递归法、迭代法)的运行时间,评估效率。

实验步骤:1. 初始化参数:确定模拟的总人数n和报数间隔m。

2. 创建一个循环队列模拟人们围成的圈。

3. 通过循环和条件判断模拟报数和出圈过程。

4. 记录每次出圈的人的编号和最终剩下的人的位置。

5. 改变n和m的值,重复步骤1至4,收集多组数据。

6. 分析数据,寻找出圈规律。

7. 对模拟过程进行计时,比较不同算法的运行时间。

实验结果:1. 通过大量实验数据,发现当n和m的值较小时,可以直观看出出圈顺序的规律。

2. 随着n和m值的增大,出圈顺序变得更加复杂,但依然存在一定的规律性。

3. 实验中使用的迭代法在处理大规模数据时,相比递归法具有更高的效率,递归法在深度较大时可能会导致栈溢出。

4. 通过图表展示了不同n和m值下,最后剩下的人的位置的概率分布。

实验结论:1. 约瑟夫问题的出圈顺序并非完全随机,存在一定的数学规律。

2. 迭代法在解决大规模约瑟夫问题时更为高效和稳定。

3. 本实验为进一步研究约瑟夫问题提供了实验数据和算法优化方向。

建议:对于未来的研究,可以尝试将约瑟夫问题推广到更多变种,如双向报数、不同方向报数等,以及探索其在实际问题中的应用,如网络协议设计、资源分配等。

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

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

约瑟夫问题数据结构实验报告[正文]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.问题描述:约瑟夫问题的一种描述是:编号为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。

北邮数据结构实验一题目4

北邮数据结构实验一题目4
C++实现:
if(m==1)
{
cout<<"最后出列的是:"<<n<<endl;
return;
}
关键算法2:
删除每次循环的第m号数据。实现时用头指针移动,查找第m-1个数据,然后删除第m个数据,头指针后移。
伪代码:
1.借助first指针,first指针后移,移动m-1次。
2.建立临时指针变量指向m个数据。
存储结构:单链循环链表
示意图如下:
2.2关键算法分析
关键算法思想描述和伪代码描述:
关键算法1:
将轮流次数为特殊数字1时单独考虑,解决不带头结点的链表带来的循环人数为1和大于1时操作不一致的问题。
伪代码:
1.判断循环人数是否为1。
2.如果是则直接输出从1——n的出列顺序,结束程序。
3.如果不是则继续后面的代码。
2、初始时没有将m=1情况单独考虑,由于不带空头结点,无法查找1个结点的前一个结点,因而当m=1时出错。后把m=1直接单独处理,避免没有头结点的情况下无法将删除头结点于其他节点相同处理的情况,也避免了建立了链表之后单独处理m=1时析构每个节点的操作。
3、心得体会,编程解决约瑟夫问题需要对链表的构造、有无头结点的操作十分熟悉,对删除节点时要更加细心。在写程序的过程中,应该时刻注意程序完备性,对堆内存操作时避免内存泄漏和指针悬挂。在写算法时,选择合适的存储结构十分重要,甚至可以事半功倍。
3.first指针指向m+1个数据。
4.delete第m个数据。
C++实现:
for(intj=1;j<m-1;j++)
{
first=first->next;

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

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

约瑟夫问题数据结构实验报告实验概述本实验旨在通过实现约瑟夫问题的求解算法,深入理解链表数据结构的应用,以及算法的时间复杂度分析。

实验将通过编写程序来模拟约瑟夫问题,并测试不同规模下的时间性能,从而验证算法的准确性和效率。

实验目的●理解约瑟夫问题的定义和求解算法●掌握链表数据结构的基本操作●理解算法的时间复杂度分析方法实验内容1·约瑟夫问题约瑟夫问题是一个经典的数学问题,描述如下:n个人围成一圈,从第一个人开始报数,报到m的人出圈,然后从出圈的下一个人重新开始报数,直到剩下最后一个人。

2·数据结构设计为了解决约瑟夫问题,我们可以使用循环链表来表示n个人围成的圈。

链表节点的数据域存储每个人的编号,指针域指向下一个人。

3·算法设计约瑟夫问题的求解算法如下:1·创建一个循环链表,并初始化n个人的编号。

2·从第一个人开始,依次报数m次,直到找到第m个人。

3·将第m个人从链表中删除。

4·重复步骤2和3,直到只剩下最后一个人。

4·程序实现下面是约瑟夫问题求解算法的主要实现步骤:1·定义一个循环链表的结构,并实现链表的初始化操作。

2·实现算法的主函数,用于接收输入参数n和m,并调用其他函数进行求解。

3·实现一个函数,用于模拟报数过程,并返回每次报数的人的编号。

4·实现一个函数,用于删除链表中指定位置的节点。

5·实现一个函数,用于遍历链表,输出剩下的最后一个人的编号。

实验结果及分析在实验中我们分别测试了5个人和10个人的情况,对比了不同m值下的运行时间,并绘制了相应的曲线图。

实验结果表明,约瑟夫问题的求解算法在不同规模下的时间复杂度为O(nm),其中n为人数,m为报数值。

随着m值的增大,算法的运行时间也呈指数级增长。

附件本文档所涉及的附件包括:●源代码文件●实验结果数据文件●曲线图文件法律名词及注释本文档没有涉及法律名词及注释。

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

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

数据结构约瑟夫环实验报告数据结构约瑟夫环实验报告引言:数据结构是计算机科学中的重要概念,它涉及如何组织和存储数据以便有效地使用。

约瑟夫环是一种经典的数据结构问题,它涉及到一个有序的列表,以及在列表中进行操作的规则。

在本次实验中,我们将探索约瑟夫环的概念,并通过编写程序来模拟和解决约瑟夫环问题。

背景:约瑟夫环问题源于一个古老的传说,故事中有一群囚犯被困在一个圆形的牢房中。

为了避免被敌人发现,囚犯们决定采取一种特殊的方式来决定谁将被处决。

开始时,他们围成一个圆圈,从一个固定的位置开始数,每次数到一个固定的数字,该数字的人将被处决。

然后,从被处决的人开始重新数数,直到只剩下一个人。

实验过程:为了模拟约瑟夫环问题,我们首先需要创建一个循环链表。

循环链表是一种特殊的链表,其最后一个节点指向第一个节点,形成一个环形结构。

在这个环形链表中,我们将存储囚犯的信息,包括编号和姓名。

在编写程序之前,我们需要定义一些参数。

首先,我们需要确定囚犯的总人数和每次数数的数字。

这些参数可以根据实际情况进行调整。

接下来,我们需要定义一个起始位置,即从哪个囚犯开始数数。

在创建循环链表后,我们将开始模拟约瑟夫环问题。

我们将从起始位置开始数数,每当数到指定的数字时,我们将删除当前节点,并将数数的位置移动到下一个节点。

这个过程将一直进行,直到只剩下一个节点为止。

结果与分析:通过运行程序,我们可以得到约瑟夫环问题的解。

最后一个幸存的囚犯的编号将被输出。

通过不同的参数设置,我们可以观察到不同的结果。

在实验过程中,我们还可以观察到一些有趣的现象。

例如,当囚犯的总人数和每次数数的数字相等时,最后一个幸存的囚犯将是初始位置的囚犯。

这是因为每次数数后,数数的位置都会移动到下一个节点,因此初始位置的囚犯将是最后一个被删除的节点。

此外,我们还可以观察到约瑟夫环问题的时间复杂度。

在每次删除节点时,我们需要遍历整个链表以找到要删除的节点。

因此,如果囚犯的总人数很大,这个过程可能会非常耗时。

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

数据结构实验报告实验名称:实验一——线性表学生姓名:班级:班内序号:学号:日期:1.实验要求(1)实验目的通过选择下面四个题目之一进行实现,掌握如下内容:熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法学习指针、模板类、异常处理的使用掌握线性表的操作的实现方法学习使用线性表解决实际问题的能力(2)实验内容利用循环链表实现约瑟夫问题的求解。

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

从序号为1的人开始报数,顺时针数到m的那个人出列;他的下一个人又从1开始报数,数到m 的那个人又出列;依此规则重复下去,直到所有人全部出列。

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

2. 程序分析2.1 存储结构存储结构为单循环链表,线性表简称表,是由零个或多个具有相同类型的数据元素构成的有限序列。

链表为了正确表示结点间的逻辑关系,在存储每个元素值的同时,还要存储该元素的直接后继元素的位置信息,这两部分信息构成了实际的存储结构,称为结点。

此循环链表只为解决约瑟夫问题,所以有参构造函数让尾指针存储着最后一个元素的数据,然后指向第一个元素,形成单循环链表。

如图:(rear)2.2 关键算法分析1.关键算法约瑟夫问题的实质就是在含n个元素的循环链表中依次删除第m个元素,返回链表中最后一个元素值。

即用含那n个元素的数组初始化循环链表,从第一个元素开始查找第m-1个元素,删除第m个元素,然后从第m+1个元素开始继续查找第m-1个元素,删除第m个元素,循环此过程直到链表中只剩下最后一个元素。

关键算法伪代码如下:[1] 让用户输入要删第几个元素和总人数n,并给含n个元素的数组赋值;[2] 用含n个元素的数组初始化循环链表(头插法);[3] 调用单循环表类的删除函数,实参为数组和尾指针的下一结点(即第一个元素);[3.1] 定义新结点p,用以存储要删除的结点;[3.2] 进行循环找到要删除元素的上一结点;[3.3] 初始化指针p指向b->next,p的指针域指向b的指针域,第m个元素摘链,删除p,指针b后移,人数n自减1;[3.4.1] 判断如果n等于1,输出剩下一元素的序号,然后删除最后一结点,此为递归结束条件;[3.4.2] 判断如果n大于1,则进行自身递归调用,直至遇到结束条件停止;[3.4.3] 如果n等于0,即一开始链表只有一个结点,输出“无人剩下!”;2. 代码详细分析:(1)删除操作的算法步骤:①从第一个结点开始,查找第m-1个元素,设为b指向该结点;②设p指向第i个元素:p = b->next;③摘链,即将b元素从链表中摘除:b->next = p->next;④释放q元素:delete q;(2) 递归调用算法步骤:①判断如果n等于1,输出剩下一元素的序号,然后删除最后一结点,此为递归结束条件:if(n==1){cout<<”剩下一人的序号:”<<b->next->data<<endl;delete b;}②判断如果n大于1,则进行自身递归调用,直至遇到结束条件停止:else if(n>1) Delete(m,b->next,n);③如果n等于0,即一开始链表只有一个结点,输出“无人剩下!”:else if(n==0){cout<<"无人剩下!"<<endl;system("pause");}3.时间复杂度的计算[1] O(n)[2] O(n)[3] O(1)[3.1] O(1)[3.2] O(m)[3.3] O(1)[3.4.1] O(1)[3.4.2] O(n*m)[3.4.3] O(1)2.3 其他(1)在此需要说明的是,在初始化链表时,特使用了头插法,并对头插法做了相应的修改。

使尾指针rear存储着最后一个结点。

伪代码如下:[1] 用含n个元素的数组a[]初始化循环链表;[2] 尾指针的data域存储最后一个结点a[n-1];[3] 进行循环初始化新结点s存储a[i];[4] s->next=rear->next;[5] rear指向s: rear->next=s;(2)在这里为了使代码简洁,在删除函数里使用了递归调用,结束条件时只剩一个人时,并输出该人序号。

3. 程序运行结果1.流程流程图如下:2.测试条件:人数n和删除数m必须为整数。

3. 测试结论:4. 总结(1)调试时出现的问题及解决方法①在调试时出现了执行错误,在析构函数中设置了断点。

在执行时,发现析构函数停不下来,原来在删除函数里已经析构到只剩一个结点,而且尾指针可能已经被删除,所以我去掉了析构函数,而在输出最后一个结点后析构该结点。

②在执行时发现剩下一人的序号不对,在删除函数的摘链操作中设置了断点,在执行时,发现每次删除的结点不正确,原来删除函数的实参错误写为了尾指针,该为第一个结点后程序正确。

(2)心得体会在本次实验中,熟悉了单循环链表的各种基本操作,特别对插入操作、查找操作和删除操作有了较深的理解。

对于数组和指针的用法也更熟练,在程序的调试和异常处理方面有了一定的经验。

相信在本次实验中积累的经验、提高的能力将在今后的实验中展现出来。

尤其在递归函数的使用方面有了很大的提高,熟悉了递归函数使用条件,了解了要设置递归结束条件。

(3)下一步的改进程序有的代码不够简洁,可以写得更简洁,可能还有更好的方法,此程序把尾指针存储了一个元素,违反了尾指针的原意,可以进一步改进。

附代码://ClinkList.h#include<iostream>using namespace std;template<class T>struct Node//储存节点的结构{T data;struct Node<T> * next;};template<class T>class ClinkList//单循环链表类{public:ClinkList(){rear=new Node<T>;rear->next=rear;}//无参构造函数ClinkList(T a[],int n);//有参构造函数void Delete(int m,Node <T>*b,int n);//删除结点函数Node <T> * rear;//尾指针};template<class T>ClinkList<T>::ClinkList(T a[],int n)//头插法{rear =new Node <T>;rear->next=rear;rear->data=a[n-1];for(int i=n-2;i>=0;i--){Node<T>*s=new Node <T>;s->data=a[i];s->next=rear->next;rear->next=s;}}template<class T>void ClinkList<T>::Delete(int m,Node <T>*b,int n){Node <T>* p;for(int j=0;j<(m-2+n)%n;j++)//找到要删结点的前一结点{b=b->next;}p=b->next;b->next=p->next;delete p;n--;if(n==1)//递归结束条件{cout<<"剩下一人的序号是:"<<b->next->data<<endl;system("pause");delete b;}else if(n>1) Delete(m,b->next,n);//递归函数,递归删除else if(n==0){cout<<"无人剩下!"<<endl;system("pause");}}//main.cpp#include<iostream>#include"ClinkList.h"using namespace std;void main(){int m,n;cout<<"输入共有几个人:";cin>>n;cout<<"输入要删除第几个人:";cin>>m;int *a=new int [n];for(int i=0;i<n;i++)a[i]=i+1;ClinkList<int> b(a,n);//声明对象b.Delete(m,b.rear->next,n);}。

相关文档
最新文档