c语言实现约瑟夫环问题

合集下载

约瑟夫问题面向对象(C++版)程序设计报告

约瑟夫问题面向对象(C++版)程序设计报告
Jose类中的成员函数分别为:
函数
相关说明
Jose(int boys, int interval, int begin=1);
构造函数,主要功能初始化各个参数,校验输出的m、n、s参数为int boys, int interval, int begin=1
void getWinner()const;
//构造函数
//-------------------------------------
BoyRing::BoyRing(int n)
{
if(n<2) throw exception(); //发生错误时自动跳出
pBegin = new Boy[n]; //申请一个新的Boy空间,pBegin指向该空间的开始处
for(int i=1; i<=n; i++)
{
pBegin[i-1].next = &pBegin[i%n];//形成链表
pBegin[i-1].code = i;//给孩子孩子编号
}
pivot = pCurrent = &pBegin[n-1];//各指针初始化
}
//------------------------------------
2详细设计
2.1程序结构
改程序分成三个抽象层次,第一层是应用层,直接指使Jose类对象去完成求解工作;第二层是Jose类层,描述Josephus问题的求解细节;第三层是BoyRing类层,辅助Jose类完成求解过程(上述三层间的关系描述如图J-1,这也是程序模块间的关系)。
图J-1.对象实现中程序模块的相互关系
void disengage();
利用指针实现小孩离队,无参数

实验一:约瑟夫问题

实验一:约瑟夫问题

实验一:约瑟夫问题问题描述:用数组和链表存储方式实现约瑟夫问题。

约瑟夫问题:n个人围成一个圆圈,首先第1个人从1开始一个人一个人顺时针报数,报到第m个人,令其出列。

然后再从下一个人开始,从1顺时针报数,报到第m个人,再令其出列,…,如此下去,直到圆圈中只剩一个人为止。

此人即为优胜者。

基本要求:用顺序存储和链式存储方式实现。

试验报告内容:1.问题描述:设有n个人围坐在圆桌周围,现从某个位置m(1≤m≤n)上的人开始报数,报数到k 的人就站出来。

下一个人,即原来的第k+1个位置上的人,又从1开始报数,再报数到k的人站出来。

依此重复下去,直到全部的人都站出来为止。

2. 算法描述:可以先建一个单向循环链表;而整个“约瑟夫环”问题的过程,最终是把这个链表删空为止。

但在删时不能顺着删,而是按该问题的方案来删。

3.源程序#include <stdio.h>#include <stdlib.h>#define MAX_NODE_NUM 100#define TRUE 1U#define FALSE 0Utypedef struct NodeType{int id; /* 编号 */int cipher; /* 密码 */struct NodeType *next;} NodeType;/* 创建单向循环链表 */static void CreaList(NodeType **, const int);/* 运行 "约瑟夫环 "问题 */static void StatGame(NodeType **, int);/* 打印循环链表 */static void PrntList(const NodeType *);/* 得到一个结点 */static NodeType *GetNode(const int, const int);/* 测试链表是否为空, 空为TRUE,非空为FALSE */static unsigned EmptyList(const NodeType *);int main(void){int n, m;NodeType *pHead = NULL;while (1){printf( "请输入人数n(最多%d个): ", MAX_NODE_NUM); scanf( "%d ", &n);printf( "和初始密码m: ");scanf( "%d ", &m);if (n > MAX_NODE_NUM){printf( "人数太多,请重新输入!\n ");continue;}elsebreak;}CreaList(&pHead, n);printf( "\n------------ 循环链表原始打印 -------------\n "); PrntList(pHead);printf( "\n-------------- 出队情况打印 ---------------\n "); StatGame(&pHead, m);printf( "\n\ "约瑟夫环\ "问题完成!\n ");return 0;}static void CreaList(NodeType **ppHead, const int n){int i, iCipher;NodeType *pNew, *pCur;for (i = 1; i <= n; i++){printf( "输入第%d个人的密码: ", i);scanf( "%d ", &iCipher);pNew = GetNode(i, iCipher);if (*ppHead == NULL){*ppHead = pCur = pNew;pCur-> next = *ppHead;}else{pNew-> next = pCur-> next;pCur-> next = pNew;pCur = pNew;}}printf( "完成单向循环链表的创建!\n ");}static void StatGame(NodeType **ppHead, int iCipher){int iCounter, iFlag = 1;NodeType *pPrv, *pCur, *pDel;pPrv = pCur = *ppHead;/* 将pPrv初始为指向尾结点,为删除作好准备 */while (pPrv-> next != *ppHead)pPrv = pPrv-> next;while (iFlag) /* 开始搞了! */{/* 这里是记数,无非是移动iCipher-1趟指针! */for (iCounter = 1; iCounter < iCipher; iCounter++) {pPrv = pCur;pCur = pCur-> next;}if (pPrv == pCur) /* 是否为最后一个结点了 */iFlag = 0;pDel = pCur; /* 删除pCur指向的结点,即有人出列 */pPrv-> next = pCur-> next;pCur = pCur-> next;iCipher = pDel-> cipher;printf( "第%d个人出列, 密码: %d\n ",pDel-> id, /* 这个编号标识出列的顺序 */pDel-> cipher);free(pDel);}*ppHead = NULL; /* 没人了!为了安全就给个空值 */}static void PrntList(const NodeType *pHead){const NodeType *pCur = pHead;if (EmptyList(pHead))return;do{printf( "第%d个人, 密码: %d\n ", pCur-> id,pCur-> cipher); pCur = pCur-> next;} while (pCur != pHead);}static NodeType *GetNode(const int iId, const int iCipher){NodeType *pNew;pNew = (NodeType *)malloc(sizeof(NodeType));if (!pNew){printf( "Error, the memory is not enough!\n ");exit(-1);}pNew-> id = iId;pNew-> cipher = iCipher;pNew-> next = NULL;return pNew;}static unsigned EmptyList(const NodeType *pHead){if (!pHead){printf( "The list is empty!\n ");return TRUE;}return FALSE;}4.实验测试数据(要求有多组):第一组测试结果人数n为7, 初始密码m为20第1个人, 密码: 3第2个人, 密码: 1第3个人, 密码: 7第4个人, 密码: 2第5个人, 密码: 4第6个人, 密码: 8第7个人, 密码: 4-------------- 出队情况打印 ---------------第6个人出列, 密码: 8第1个人出列, 密码: 3第4个人出列, 密码: 2第7个人出列, 密码: 4第2个人出列, 密码: 1第3个人出列, 密码: 7第5个人出列, 密码: 4第二组测试结果人数n为8, 初始密码m为15第1个人, 密码: 5第2个人, 密码: 4第3个人, 密码: 3第4个人, 密码: 2第5个人, 密码: 9第6个人, 密码: 1第7个人, 密码: 7第8个人, 密码: 8-------------- 出队情况打印 ---------------第7个人出列, 密码: 7第6个人出列, 密码: 1第8个人出列, 密码: 8第3个人出列, 密码: 3第1个人出列, 密码: 5第4个人出列, 密码: 2第2个人出列, 密码: 4第5个人出列, 密码: 95.总结:1. 通过本次上机实践,对链表存储结构有了更深的理解和把握.2. 通过本次上机实践,应用链表的知识解决和分析问题的能力有了新的提高.3. 通过上机实践,掌握了用高级语言实现算法的基本步骤和方法.(最前面加班级、学号、姓名)。

数据结构C语言版部分习题及答案[2]

数据结构C语言版部分习题及答案[2]

第二章习题与解答一判断题1.线性表的逻辑顺序与存储顺序总是一致的。

2.顺序存储的线性表可以按序号随机存取。

3.顺序表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。

4.线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此是属于同一数据对象。

5.在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。

6.在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。

7.线性表的链式存储结构优于顺序存储结构。

8.在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。

9.线性表的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。

10.在单链表中,要取得某个元素,只要知道该元素的指针即可,因此,单链表是随机存取的存储结构。

二单选题 (请从下列A,B,C,D选项中选择一项)1.线性表是( ) 。

(A) 一个有限序列,可以为空;(B) 一个有限序列,不能为空;(C) 一个无限序列,可以为空;(D) 一个无序序列,不能为空。

2.对顺序存储的线性表,设其长度为n,在任何位置上插入或删除操作都是等概率的。

插入一个元素时平均要移动表中的()个元素。

(A) n/2 (B) n+1/2 (C) n -1/2 (D) n3.线性表采用链式存储时,其地址( ) 。

(A) 必须是连续的;(B) 部分地址必须是连续的;(C) 一定是不连续的;(D) 连续与否均可以。

4.用链表表示线性表的优点是()。

(A)便于随机存取(B)花费的存储空间较顺序存储少(C)便于插入和删除(D)数据元素的物理顺序与逻辑顺序相同5.某链表中最常用的操作是在最后一个元素之后插入一个元素和删除最后一个元素,则采用( )存储方式最节省运算时间。

(A)单链表(B)双链表(C)单循环链表(D)带头结点的双循环链表6.循环链表的主要优点是( )。

(A)不在需要头指针了(B)已知某个结点的位置后,能够容易找到他的直接前趋(C)在进行插入、删除运算时,能更好的保证链表不断开(D)从表中的任意结点出发都能扫描到整个链表7.下面关于线性表的叙述错误的是( )。

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

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

约瑟夫环实验报告总结【篇一:约瑟夫环实验报告】实验报告课程名称:数据结构实验名称:顺序表和链表的应用实验编号:实验一指导教师:一、实验目的(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)主要的函数或操作内部的主要算法,分析这个算法的时、空复杂度,并说明设计的巧班级:学号:姓名:组号:实验成绩:批阅教师签字:实验日期:实验时间:妙之处。

约瑟夫问题的C++代码

约瑟夫问题的C++代码

#include<iostream>using namespace std;struct Node//定义节点的结构类型{int data;Node* next;};class CircularLinkedList//循环链表类{public:CircularLinkedList(){first=new Node;first->next=NULL;}CircularLinkedList(int n);//构建一个附有值的循环链表~CircularLinkedList();int Josephus(int num);//约瑟夫函数private:Node* first;};CircularLinkedList::CircularLinkedList(int n){first=new Node;Node * r=first;for(int i=1;i<=n;i++){Node* s=new Node;s->data=i;s->next=NULL;r->next=s;r=s;} //头插法初始化链表r->next=first; //最后一个元素的next志指向头结点}CircularLinkedList::~CircularLinkedList(){Node* p=first,*q;while(p->next!=first)//p指向最后一个结点时结束循环{q=p;p=p->next;delete q;}delete p;//删除头结点}int CircularLinkedList::Josephus(int num){Node* p=first,*q;if(num<=0)throw "输入错误!";while(first->next->next!=first){for(int i=1;i<num;i++) //p向后移动num位,指向要删除的元素的前一个结点{p=p->next;if(p==first) //若循环过程中出现p指向头结点,则跳过头结点{p=p->next;}}if(p->next==first) //若循环结束后p指向最后一个元素,则要跳过头结点,并让头结点的next指向要删除元素的下一个{p=first;q=p->next;p->next=q->next;//first->next=q->next;cout<<q->data<<" ";delete q;}else{q=p->next;p->next=q->next;cout<<q->data<<" ";delete q;}}cout<<endl;cout<<"最后一个数为:";return first->next->data;}void main(){int n,m;cout<<"请输入约瑟夫问题的人数和间隔人数:";cin>>n>>m;cout<<"依次删除:"<<endl;CircularLinkedList Josephus1(n);//创建的对象调用第二个构造函数cout<<Josephus1.Josephus(m)<<endl;}。

《数据结构——C语言描述》习题及答案耿国华

《数据结构——C语言描述》习题及答案耿国华

第1章绪论习题一、问答题1. 什么是数据结构?2. 四类基本数据结构的名称与含义。

3. 算法的定义与特性。

4. 算法的时间复杂度。

5. 数据类型的概念。

6. 线性结构与非线性结构的差别。

7. 面向对象程序设计语言的特点。

8. 在面向对象程序设计中,类的作用是什么?9. 参数传递的主要方式及特点。

10.抽象数据类型的概念。

二、判断题1. 线性结构只能用顺序结构来存放,非线性结构只能用非顺序结构来存放。

2. 算法就是程序。

3. 在高级语言(如C、或PASCAL)中,指针类型是原子类型。

三、计算下列程序段中XX1 的语句频度fori1iltni forj1jltij fork1kltjk xx1 提示: i1 时:1 11×1/2 112/2 i2 时:12 12×2/2 222/2 i3 时:123 13×3/2 332/2 … in 时:123……n 1n×n/2 nn2/2 fn 123……n 12 22 32 …… n2 / 2 1nn/2 nn12n1/6 / 2 nn1n2/6 n3/6n2/2n/3区分语句频度和算法复杂度:Ofn On3 四、试编写算法求一元多项式Pnxa0a1xa2x2a3x3…anxn 的值Pnx0,并确定算法中的每一语句的执行次数和整个算法的时间复杂度,要求时间复杂度尽可能的小,规定算法中不能使用求幂函数。

注意:本题中的输入aii01…n x 和n,输出为Pnx0.通常算法的输入和输出可采用下列两种方式之一:(1)通过参数表中的参数显式传递;(2)通过全局变量隐式传递。

试讨论这两种方法的优缺点,并在本题算法中以你认为较好的一种方式实现输入和输出。

提示:floatPolyValuefloat a float x int n…… 核心语句:p1 x 的零次幂s0 i 从0 到n 循环ssaip ppx 或:px x 的一次幂sa0 i 从1 到n 循环ssaip ppx 实习题设计实现抽象数据类型“有理数”。

数据结构-c语言描述(第二版)答案耿国华编著

数据结构-c语言描述(第二版)答案耿国华编著

第 3 章 限定性线性表 — 栈和队列
第三章答案
1 按 3.1(b)所示铁道(两侧铁道均为单向行驶道)进行车厢调度,回答: (1) 如进站的车厢序列为 123,则可能得到的出站车厢序列是什么? (2) 如进站的车厢序列为 123456,能否得到 435612 和 135426 的出站序列,并说 明原因(即写出以“S”表示进栈、 “X ”表示出栈的栈序列操作) 。 【解答】 (1)可能得到的出站车厢序列是:123、132、213、231、321。 (2)不能得到 435612 的出站序列。 因为有 S(1)S(2)S(3)S(4)X(4)X(3)S(5)X(5)S(6)S(6),此时按照“后进先出”的原 则,出栈的顺序必须为 X(2)X(1)。 能得到 135426 的出站序列。 因为有 S(1)X(1)S(2)S(3)X(3)S(4)S(5)X(5)X(4)X(2)X(1)。 3 给出栈的两种存储结构形式名称,在这两种栈的存储结构中如何判别栈空与栈满? 【解答】 (1)顺序栈 (top 用来存放栈顶元素的下标) 判断栈 S 空:如果 S->top==-1 表示栈空。 判断栈 S 满:如果 S->top==Stack_Size-1 表示栈满。 (2) 链栈(top 为栈顶指针,指向当前栈顶元素前面的头结点) 判断栈空:如果 top->next==NULL 表示栈空。 判断栈满:当系统没有可用空间时,申请不到空间存放要进栈的元素,此时栈满。
2.选择题
(1) A (2) 已知 L 是无表头结点的单链表,且 P 结点既不是首元素结点,也不是尾元素结点。按要 求从下列语句中选择合适的语句序列。 a. 在 P 结点后插入 S 结点的语句序列是:E 、A。 b. 在 P 结点前插入 S 结点的语句序列是:H、L、I 、E、A 。 c. 在表首插入 S 结点的语句序列是:F 、M。 d. 在表尾插入 S 结点的语句序列是:L、J 、A、G。 供选择的语句有: A P->next=S; B P->next= P->next->next; C P->next= S->next; D S->next= P->next; E S->next= L; F S->next= NULL; G Q= P; H while (P->next!=Q) P=P->next; I while (P->next!=NULL) P=P->next; J P= Q; K P= L; L L= S;第1章Fra bibliotek绪 论

C语言的循环链表和约瑟夫环

C语言的循环链表和约瑟夫环

C语言的循环链表和约瑟夫环C语言的循环链表和约瑟夫环约瑟夫问题)是一个数学的应用问题,对于学习C语言四非常挺有帮助的,下面是店铺为大家搜集整理出来的有关于C语言的循环链表和约瑟夫环,一起了解下吧!循环链表的实现单链表只有向后结点,当单链表的尾链表不指向NULL,而是指向头结点时候,形成了一个环,成为单循环链表,简称循环链表。

当它是空表,向后结点就只想了自己,这也是它与单链表的主要差异,判断node->next是否等于head。

代码实现分为四部分:1. 初始化2. 插入3. 删除4. 定位寻找代码实现:1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1void ListInit(Node *pNode){int item;Node *temp,*target;cout<<"输入0完成初始化"<<endl; cin="">>item;if(!item)return ;if(!(pNode)){ //当空表的时候,head==NULLpNode = new Node ;if(!(pNode))exit(0);//未成功申请pNode->data = item;pNode->next = pNode;}else{//for(target = pNode;target->next!=pNode;target = target->next);4 15 16 17 18 19 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3temp = new Node;if(!(temp))exit(0);temp->data = item;temp->next = pNode;target->next = temp;}}}void ListInsert(Node *pNode,int i){ //参数是首节点和插入位置Node *temp;Node *target;int item;cout<<"输入您要插入的值:"<<endl; cin="">>item;if(i==1){temp = new Node;if(!temp)exit(0);temp->data = item;for(target=pNode;target->next != pNode;target = target->next);temp->next = pNode;target->next = temp;pNode = temp;}else{target = pNode;for (int j=1;j<i-1;++j) target="target-">next;temp = new Node;if(!temp)exit(0);temp->data = item;temp->next = target->next;target->next = temp;}}void ListDelete(Node *pNode,int i){Node *target,*temp;if(i==1){for(target=pNode;target->next!=pNode;target=target ->next);temp = pNode;//保存一下要删除的首节点 ,一会便于释放6 37 38 39 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5pNode = pNode->next;target->next = pNode;temp;}else{target = pNode;for(int j=1;j<i-1;++j) target="target-">next;temp = target->next;//要释放的nodetarget->next = target->next->next;temp;}}int ListSearch(Node *pNode,int elem){ //查询并返回结点所在的位置Node *target;int i=1;for(target = pNode;target->data!=elem && target->next!= pNode;++i)target = target->next;if(target->next == pNode && target->data!=elem)return 0;else return i;}</i-1;++j)></i-1;++j)></endl;></endl;>5 96 0 6 1 6 2 6 3 6 4 6 5 6 6 67 68 69 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 8约瑟夫问题约瑟夫环(约瑟夫问题)是一个数学的'应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。

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

(一)基本问题1•问题描述设有编号为1,2,…小的n (n> 0)个人围成一个圈,每个人持有一个密码m。

从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m 时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。

当任意给定n和m后,设计算法求n个人出圈的次序。

建立模型,确定存储结构。

对任意n个人,密码为m, 实现约瑟夫环问题。

2.数据结构设计首先,设计实现约瑟夫环问题的存储结构。

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

将循环链表的结点定义为如下结构类型:struct Node{int data;Node *n ext;};其次,建立一个不带头结点的循环链表并由头指针first指示3.算法设计1、工作指针first, r, s, p, q初始化2、输入人数(n)和报数(m)3、循环n次,用尾插法创建链表Node *q;for(i nt i=1;i<=n ;i++){Node *p;p=new Node;p-> data =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 结点的后一结点q q=p->next;p->next=q->next; *L = p->next; 报出位置后Delete q; 计数器i++; 运行流程图开始代码和相关解释#in clude<iostream>using n amespace std;struct Node//循环节点的定义{int data;// 编号Node *n ext;};Node *CreateList(Node *L,i nt &n,int &m);〃建立约瑟夫环函数void Joseph(Node *L,int n,int m);〃输出每次出列号数函数Node *DeleteList(Node **L,i nt i,Node *q);〃寻找每次出列人的号数int LengthList(Node *L);〃计算环上所有人数函数void main()// 主函数〃在主函数中,完成人数(n)和报数(m)的输入和工作指针的初始化{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->data=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->data<<endl;delete q;// 释放出列人的存储空间}cout<<" 最后一个出列号数是:"<<L->data<<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){p=p->next;return(i);复杂度分析:for(i nt i=1;i<=n ;i++){Node *p;p=new Node; p->nu mber=i; p-> next=NULL; if(i==1) L=q=p; else{q_>next=p;q=q_>next;}时间复杂度:O (n)if(i==1) i+=Le ngthList(*L);Node *p;p=*L;int j=0;while(j<i-2) {p=p->n ext;j++;}q = p_>n ext;p->n ext=p->n ext->n ext;*L = p_>n ext;return(q);时间复杂度:O (n2) 算法的空间复杂度:O (n2)4•界面设计请输入报数人数n 请输入所报数M 请输入第一个报数人以下列出依次报数的结果5.运行、测试与分析(二)采用顺序存储结构如何实现约瑟夫环问题代码和解释#i nclude <stdlib.h>#in clude<stdio.h>#in clude<malloc.h>#defi ne MaxSize 50typedef char ElemType;typedef struct Seqlist{//线性表顺序存储结构定义ElemType *elem[MaxSize];〃存放顺序表数据元素 int length;//当前长度}*JSeqlist;〃线性表存储结构类型名JSeqlist In t_SeqList(void){//顺序表初始化JSeqlist L;L=(JSeqlist)malloc(sizeof(struct Seqlist)); if(L!=NULL)L->le ngth=O;else printf(" 超出范围!! "); 人 h 数 6Ml g 第岀列顺序:return L;}ElemType *Locate_SeqList(JSeqlist L,int p){//查找线性表中下标为P的元素if(p>=0&&L->length)return(L->elem[p]);else{printf(" 顺序表中不存在相关元素");return NULL;}}int Insert_SeqList(JSeqlist L,int i,ElemType *x) {//在顺序表中指定元素前插入Xint j;if(L->length==MaxSize)//L.length 是最后一个元素的位置{printf(" 线性表已满,无法进行插入操作!!!!\n");return 0;}if(i<0||i>L->length){printf(" 插入位置不对,超出顺序表长度\n");return 0;}if(i==0){L->elem[i]=x;L->length=L->length+1;return 1;}for(j=L->length;j>=i;j--){L->elem[j]=x;}L->length++;return 1;}int Delete_JSeqlist(JSeqlist L,int i){//在顺序表中删除第i 个元素int j;if(i<0||i>L->length-1){printf(" 删除位置不对,超出顺序表的长度啦\n"); return 0;}for(j=i;j<L->length-1;j++)L->elem[j]=L->elem[j+1];L->length--;return 1;}void josephus(JSeqlist L,int start,int m){//josephus 问题求解的非常牛逼的函数int s,i;ElemType *w;s=start-1;for(i=L->length;i>0;i--){s=(s+m-1)%i;w=Locate_SeqList(L,s);printf(" 出列人员为:%s\n",w);Delete_JSeqlist(L,s);}}int main (void){JSeqlist Josephus;int n,m,i,k,s;Josephus=Int_SeqList();// 顺序表初始化printf(" 约瑟夫环问题顺序表求解_愚人节特别版\n\n");printf(" 请输入本问题中总人数m=");scanf("%d",&n);printf(" 请输入本问题开始人员的位置S=");scanf("%d",&s);printf(" 请输入本问题的计数值m=");scanf("%d",&m);printf(" 请输入本问题中这些人的名字\n");for(i=0;i<n;i++){printf(" 第%d 位置的人员的名字为:",(i+1));Josephus->elem[i]=(ElemType *)calloc(10,sizeof(char));scanf("%s",Josephus->elem[i]);k=Insert_SeqList(Josephus,i,Josephus->elem[i]);if(k==0)exit(1);}josephus(Josephus,s,m);free(Josephus);getchar();return 0;}运行结果(三)密码不同#in elude <iostream.h>struct CList{int password;int nu mber; struct CList *n ext;};typedef struct CList CNode;typedef CNode *CL ink;CLink CreateList(int length){CLink head;CLink before;CLink new_no de;int i;head=new CNode;if(head==NULL)return NULL;cout << "Please In put Password 1 :" << en dl; cin >> head->password;head->nu mber=1;head-> next=NULL;before=head;约 I D II 回] 九人^§一.」 题邇题談 ' L;\Users \MrZhao\De&ktc p\jySiSug\Cpp210.exe" 敢字Ifl 嗨位3 吴瑕爱晓 - 一名名名名«嗒 O •a彌爛:|翠採" 瞥直置直置置吕躺-吕H A -5鳥 1 12 3456夕禺歹勺.歹段0 佳.|=第弟J .S^-Hfor(i=1;i<length;i++){new_node=new CNode; if(new_node == NULL) return NULL;new_node->number = i+1;cout << "Please Input Password " << new_node->number << ":" <<endl; cin >>new_node->password;new_node->next = NULL; before->next=new_node;before=new_node;}new_node->next =head;return head;}int main(){CLink head;CLink ptr,back,last;int i,j,m,n;cout << "Please Input the Number of Persons: " << endl;cin >> n;cout << "Please Input the First Password M: " << endl; cin >> m;head=CreateList(n);ptr=head; for(i=0;i<n;i++){for(j=0;j<m-1;j++){back=ptr;// 定位最后一个数的接点赋值给back ptr=back->next;}cout <<" 第"<<i+1<<" 个出列的编号为:"<<ptr->number<<endl; m=ptr->password;if(ptr==head){last=head; while(last->n ext!=head) last=last- >n ext; last->n ext=head->n ext; delete ptr;ptr=last- >n ext; head=ptr;}else{back- >n ext=ptr- >n ext; delete ptr;ptr=back- >n ext;}}return 0;}运行结果s2:6-3:4=5 con t in Lie (三)心得体会:1•编程是个很细致的工作,尤其是在写顺序表的时候,涉及的函数很多,函数名中最初为了 看在清扁扁扁扁扁扁■y 川列那列511列3 出出出出出出a ?JTXr [njputtliD Hunibcii* of* Poissons s I n]put tlio Fli*e t PasBwoi-d. M =:e [n]put 1 np'ut Pas E VJMD 2=1 njpiut Pas s vw i*d 3=t input Pa.3 EldOF fi4: se [input Pas s : I >JOpdse 【nwit Password ft :nunbei* front whon start witzli■ " B C\U Ecrs^W rZhao\Dc is IctoRjBd&gWV 不同的瓷码' De bug\Cpp^cx«" 号号号号号号t晰,涉及成单词首字母是大写的,但是后来在函数调用的时候,就忘记了最初命名的时候是大写的了,导致编译的时候不能识别。

相关文档
最新文档