文档库 最新最全的文档下载
当前位置:文档库 › 约瑟夫环的循环链表实现讲解

约瑟夫环的循环链表实现讲解

约瑟夫环的循环链表实现讲解
约瑟夫环的循环链表实现讲解

约瑟夫环的循环链表实现

#include

#include

#define NUMBER 13 //可以通过输入确定人的个数

#define NEXT 8 //确定报数的间隔数

#define LENGTH sizeof(MEN

#define NULL 0

struct men

{

int number;

struct men *pMen;

};

typedef struct men MEN;

/********************************************/ /* 约瑟夫环的循环链表实现 */

/********************************************/ void main(

{

MEN *pOne = NULL, *pTwo = NULL, *pHead =NULL; int client;

/*

* 创建环形链表

*/

pHead = pOne = pTwo = (MEN *malloc(LENGTH;

pHead->number = 1;

for (client = 2; client <= NUMBER; client++

{

pOne = (MEN *malloc(LENGTH;

pTwo->pMen = pOne;

pOne->number = client;

pTwo = pOne;

}

pOne->pMen = pHead;

/*

* 进行操作

*/

pTwo = pHead;

pOne = pTwo->pMen;

while(pOne->pMen != pTwo

{

for(client = 0; client < NEXT - 2;client++

{

pTwo = pOne;

pOne = pOne->pMen;

}

// if(pOne == pHead//对于单向链表的头指针删除问题已经不存在// pHead = pOne->pMen;

// else

pTwo->pMen = pOne->pMen;

pOne = NULL;

free(pOne;

pOne = pTwo->pMen;

pOne = pOne->pMen;

pTwo = pTwo->pMen;//保持初始状态

}

printf("%d\n", pOne->number;

}

对于每一位都有一个位权的实现:

#include

#include

#define LENGTH sizeof(MEN

#define NULL 0

struct men

{

int number;

int code;

struct men *pMen;

};

typedef struct men MEN;

////////////////////////////////////////////////////////////////////////// // 约瑟夫环的循环链表实现

////////////////////////////////////////////////////////////////////////// void main(

{

MEN *pOne = NULL,

*pTwo = NULL,

*pHead = NULL;

int client;

int NUMBER = 13; //设置默认的人数

int NEXT = 3; //选出的人数间隔的初始间隔数

//

// 输入人数

//

printf("请输入游戏的人数:";

scanf("%d", &NUMBER;

//

// 创建环形链表

//

pHead = pOne = pTwo = (MEN *malloc(LENGTH; if (pHead == NULL

{

printf("头结点空间分配出错!";

return;

}

//

// 初始这个链表,对头结点进行赋值

//

pHead->number = 1;

printf("请输入第1位的密码:";

scanf("%d", &pHead->code;

for (client = 2; client <= NUMBER; client++

{

pOne = (MEN *malloc(LENGTH;

if(pOne == NULL

{

printf("空间分配出错!";

return;

}

pTwo->pMen = pOne;

pOne->number = client;

printf("请输入第%d位的密码:", client;

scanf("%d", &pOne->code;

pTwo = pOne;

}

pOne->pMen = pHead;

printf("\n被选出的次序:\n";

//

// 进行操作

//

pTwo = pHead;

pOne = pTwo->pMen;

while(pOne->pMen != pTwo

{

for(client = 0; client < NEXT - 2;client++ {

pTwo = pOne;

pOne = pOne->pMen;

}

// if(pOne == pHead//对于单向链表的头指针删除问题已经不存在// pHead = pOne->pMen;

// else

pTwo->pMen = pOne->pMen;

//

// 释放不用的结点

//

printf(" %d ", pOne->number;

NEXT = pOne->code;

pOne = NULL;

free(pOne;

pOne = pTwo->pMen;

pOne = pOne->pMen;

pTwo = pTwo->pMen;//保持初始状态

}

printf("%d", pTwo->number;

printf("\n最后留下的是:%d\n", pOne->number;

}

约瑟夫环课程设计实验报告

《数据结构》 课程设计报告 课程名称:《数据结构》课程设计课程设计题目: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; /删除的是尾结点时(不知道为什么我写程序里总是编译出现错误){ q->next=head; //重新链接 delete a; len--; return out; } else { q->next=a->next; delete a; len--; return out; } } } } 5、测试结果:

双向循环链表的建立插入与删除

创建双向循环链表的源代码: #include #include #define OVERFLOW -2 #define ERROR 0 #define OK 1 typedef int status; //双向循环链表的存储结构 typedef struct DuLNode { int data; int Length; struct DuLNode *prior; struct DuLNode *next; } DuLNode,*DuLinkList; //构建一个空的双向循环链表 void InitList(DuLNode **p) { *p=(DuLNode *)malloc(sizeof(DuLNode)); if(*p) { (*p)->next=(*p)->prior=*p; (*p)->Length=0; } else exit(OVERFLOW); } //双向循环链表的创建 void Create(DuLinkList &L,int n) { //输入n个元素的值,建立带头结点的双线循环链表L DuLinkList p=L,q; int i; for(i=1;i<=n;i++) { q=(DuLinkList)malloc(sizeof(DuLNode)); printf("您该输入第%d个元素的值了:",i); scanf("%d",&q->data); p->next =q; q->prior=p; q->next=L; L->prior =q; p=q;

L->Length ++; } } //结点的输出 void Display( DuLinkList L) { DuLinkList p; printf("双向循环链表中的结点的数据为:"); for(p=L->next ;p->next !=L;) { printf("%d",p->data); printf(" 、"); p=p->next ; } printf("%d\n",p->data ); } int main() { DuLinkList L; int n,i; InitList(&L) ; printf("你想创建几个循环节点就输入几就行啦,请输入:"); scanf("%d",&n); Create(L,n); Display(L); } 双向循环链表插入源代码: #include #include #define OVERFLOW -2 #define ERROR 0 #define OK 1 typedef int status; //双向循环链表的存储结构 typedef struct DuLNode { int data; int Length; struct DuLNode *prior; struct DuLNode *next; } DuLNode,*DuLinkList; //构建一个空的双向循环链表

约瑟夫问题算法及数据结构课程设计报告

线性表的操作及其应用 一、问题描述 线性表、队列是一种常用的数据结构,有顺序和链式两种存储结构,在实际中应用十分广泛,而链表又分为单链表和循环链表,队列又分为链式队列和循环队列。这些数据结构都可用来解决约瑟夫环问题。约瑟夫环问题是算法设计中的一个经典问题,是顺序编号的一组n个人围坐一圈,从第1个人按一定方向顺序报数,在报到m时该人出列,然后按相同方法继续报数,直到所有人出列。设计算法求约瑟夫环中人员的出列顺序。 二、基本要求 1、选择合适的存储结构,建立线性表; 2、利用顺序存储结构求解约瑟夫环问题; 3、利用单链表和循环链表分别求解约瑟夫环问题; 4、利用队列求解约瑟夫环问题。 三、测试数据 约瑟夫环的测试数据为7,报数为1至3。 四、算法思想 由于用到四种不同的存储结构,它们的算法思想依次是: 1、首先建立一个顺序表模拟整个约瑟夫环,手动输入顺序表长(即参加约瑟夫循环的人数)和循环的次数和表元素。用已经输出总人数和顺序表长作比较,作为外层循环条件。并对每一个输出后的元素重新赋值以为标记。对于每次循环,首先检查顺序表此次是不是我们设立的标记,如果不是则循环次数加1,当达到要求的循环次数时就将循环次数设置为0,输出该元素到屏幕并将总输出元素加1。每次外循环我们都会移到表的下一个位置,作为新的判断条件,每次报到表尾的时候,我们都将重新设置到表尾,作为下次循环的表元素。 2、首先采用链式循环链表建立整个约瑟夫环,手动输入第一次的循环次数和每个人所持下一个循环次数。设立判断指针指向表头,并将该指针是否为空作为外层循环条件。做一个内层循环,将判断指针移动到循环要输出的数,并设立一个前指针指向该指针的前一个位置,输出该元素后,将循环次数重新赋值成该元素。接着判断前指针和判断指针比较,如果相等说明整个表已经输出完毕,否则将删除该位置的元素。 3、用链式队列建立循环约瑟夫环,手动输入人数,第一次的循环次数和每个人所持下一个循环次数。并将每一个元素依次入队列,根据第一次循环次数,建立一个for循环,每一次循环都出队列,如果达到要求的循环次数就输出,否则进队列,这样这个数字就出现在队尾。第一个数输出后,以队列的非空作为循环条件,判断方式如上。 4、用循环队列建立约瑟夫环,将1-7个元素依次进入循环队列,以队列的长度作为与已输出的元素作为判断条件,对每一个输出后的元素重新赋值以为标记。对于每次循环,首先检查该该位置的元素是不是我们设立的标记-1,如果不是则循环次数加1,将队首指针移

课程设计(约瑟夫环)[1]

课程设计报告 课程名称:数据结构课程设计课程设计题目:约瑟夫环问题 姓名:余明旭 系:计算机科学与技术专业:计算机科学与技术年级:2010级 学号:100310236 指导教师:陈老师 职称:学生

一、需求分析 1、输入的形式和输入值的范围: 本程序中,输入报数上限值n,初始报数者s,初始报数者携带的密码m1,n-2个人携带的密码m(最后一人携带的密码没用),均限定为正整数,输入的形式为一个以“回车符”为结束标志的正整数。 2、输出的形式: 从屏幕显示出列顺序。 3、程序所能够达到的功能: 提供用户从键盘输入,Joseph约瑟夫环的必要数据,并显示出列顺序。4、测试数据: 输入 8 1 4 4 4 4 4 4 4 输出 4 8 5 2 1 3 7 6 一、详细设计 以单向循环链表实现该结构: 1、抽象数据类型的定义为: struct LNode { ElemType data; LNode* next; }; 2、本程序包含以下模块: 主程序模块: Void main() { 初始化; 输入数据; 执行功能; 显示结果; } 各功能模块:实现单链表的各项功能。 Void fun() { } 3、各模块的调用关系:

三、调试分析 程序的编写和调试基本正常,遇到的问题主要是:指针的指向的边界问题,如何每次正确找到出列的人的位置。 解决方法: for(int j=1;jnext; if(cp==HL) { ap=HL; cp=HL->next; } } a[i]中存储了每个人的密码,就可以准确知道每个人的位置。 通过约瑟夫环算法的课题设计让我理解了循环队列,不单单只是书本上文字的循环队列的概念,更多是自己能够通过实际的操作对循环队列有了更深的了解。上机的编程的过程是对数据结构的基础的进一步的巩固。学习过程体验到了学习的乐趣,实验课题使我认识到平时学习的漏洞和知识的缺乏,为以后的学习敲了一下警钟,数据结构是门基础,要学习扎实才行。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。 数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安 排。数据结构是数据存在的形式。 数据结构是信息的一种组织方式,其目的是为了提高算法的效率,它通常与一组算法的集合相对应,通过这组算法集合可以对数据结构中的数据进行某种操作。数据结构课程的主要目的是介绍一些常用的数据结构,阐明数据结构内在的逻辑关系,讨论它们在计算机中的存储表示,并结合各种数据结构,讨论对它们实行的 各种运算的实现算法。很多算法实际上是对某种数据结构施行的一种变换,研究算法也就是研究在实施变换过程中数据结构的动态性质。 学习的过程需要合作,而且在合作中提到自己的编程水平,借鉴他人好的地方,改掉原先自己不足,书本知识的与实际的联系,使自己的编程不在局限于原来的纸上谈兵,更多的是积累了经验,培养了能力。 四、用户手册 如何使用,详细步骤,根据提示输入。 示例: 主程序 Void main() 模块 Viod fun()

用双向循环链表求解约瑟夫环

用双向循环链表求解约瑟夫环 学校:东北大学 专业:计算机科学与技术

1.问题描述 Josephus排列问题定义如下:假设n个竞赛者排成一个环形。给定一个正整数m≤n,从第1人开始,沿环计数,第m人出列。这个过程一直进行到所有人都出列为止。最后出列者为优胜者。全部出列次序定义了1,2,…n的一个排列。称为(n,m)Josephus排列。例如,(7,3)Josephus排列为3,6,2,7,5,1,4。【实验要求】 设计求解Josephus排列问题程序。 (1)采用顺序表、单链表或双向循环链表等数据结构。 (2)采用双向循环链表实现Josephus排列问题,且奇数次顺时针轮转,偶数次逆时针轮转。 (3)推荐采用静态链表实现Josephus排列问题。 2.需求分析 本程序要求根据输入的人数n和给定的正整数m,求得约瑟夫排列,且奇数次顺时针轮转,偶数次逆时针轮转。故可利用双向循环链表建立存储结构,利用双向循环链表的遍历与删除操作实现功能要求。 3.概要设计 1.抽象数据类型定义: typedef struct DuLNode { int data; struct DuLNode *prior; struct DuLNode *next; }DuLNode,*DuLinkList; //定义双向循环链表 2.基本操作 int InitList_Dul(DuLinkList &L) //建立一个只含头结点的空双向循环链表 int CreateList_DuL(DuLinkList &L,int n) //建立一个带头结点的含n个元素的 双向循环链表L int ListDelete_DuL(DuLinkList &L,DuLinkList x) //删除指针x指向的结点 3.设计思路 首先建立一个双向循环链表作为存储结构,每个结点的数据域存储每个人的编号,然后根据给定的m值对整个链表进行遍历,找到所要找的结点后,输出该结点的数据域的值,并在双向循环链表中删除该结点,重复这样的操作,一直到所有的人都出列,依次输出的数列即为所求的Josephus排列。 4.详细设计 typedef struct DuLNode { int data; struct DuLNode *prior;

数据结构课程设计——约瑟夫环报告(含代码)

#include #include typedef struct LNode { //数据域 int cipher; //密码 int number; //编号 struct LNode *next; //指针域 }LNode,*LinkList; void InitList(LinkList &L) //创建一个只有头结点链表{ L = (LinkList)malloc(sizeof(LNode)); if(!L) { exit(1); printf("/n/nError!/n/n"); } L->next = L; } void CreateList(int n,LinkList &L) //初始化循环单链表 { LinkList p,q; q = L; printf("分别输入每个人的密码:"); for(int i = 1;i <= n;i++) { int k; scanf("%d",&k); if(k <= 0) { printf("\n\n密码有误!\n\n"); exit(1); } p = (LinkList)malloc(sizeof(LNode)); if(!p) { exit(1); printf("/n/nError!/n/n"); } p->cipher = k; p->number = i;

L->next = p; L = p; } L->next = q->next; free(q); } void PrintList(int x,int n,LinkList L) //输出出列顺序 { LinkList p,q; p = L; for(int i = 1;i <= n;i++) { for(int j = 1;j < x;j++) p = p->next; q = p->next; x = q->cipher; printf("%d ",q->number); p->next = q->next; free(q); } } int main() { printf("=============约瑟夫环==============\n\n\n"); int n,x; LinkList L; L = NULL; InitList(L); //构造空链表 printf("输入初始密码:"); scanf("%d",&x); //初始密码为x printf("\n"); printf("输入参与总人数:"); scanf("%d",&n); //总共的人数n printf("\n"); CreateList(n,L); //建立好一个约瑟夫环printf("\n\n\n===================================\n\n"); printf("出列编号为:"); PrintList(x,n,L); //输出出列顺序 printf("\n\n"); return 0; }

双向链表基本操作

双向链表 输入一个双向链表,显示些双向链表并对此双向链表排序运行结果: 源程序: #include #include #include

typedef struct Link/*双向链表结构体*/ { int data; struct Link *lift; struct Link *right; }linkx,*linky; linky Init();/*建立双向链表*/ void PrLink(linky p);/*输出双向链表*/ linky Sort(linky head);/*对双向链表排序*/ linky Swap(linky head,linky one,linky two);/*任意交换双向链表两个结点的地址*/ void main(void) { linky head; head=Init(); head=Sort(head); PrLink(head); } linky (Init())/*建立链表*/ { linky p,q,head; int n=0; head=p=q=(linky)malloc(sizeof(linkx)); printf("排序前的链表: "); scanf("%d",&p->data);/*输入数据*/ head->lift=NULL; n++; while(n!=10)/*一直输入到规定的数字个数停止*/ { q=p;

p=(linky)malloc(sizeof(linkx)); scanf("%d",&p->data);/*输入数据*/ q->right=p; p->lift=q; n++; } p->right=NULL; return(head); } linky Swap(linky head,linky one,linky two)/*任意交换两个结点*/ {linky temp; if(one->lift==NULL&&two->right==NULL)/*首和尾巴的交换*/ { if(one->right==two)/*只有两个结点的情况下*/ { two->right=one; two->lift=NULL; one->lift=two; one->right=NULL; head=two; } else/*有间隔的首尾交换*/ { one->right->lift=two; two->lift->right=one; two->right=one->right; one->lift=two->lift; two->lift=one->right=NULL; head=two;/*尾结点成为头结点*/ }

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

武汉工业学院数学与计算机学院 数据结构课程设计 设计题目:约瑟夫环 专业大类计算机 班级计算机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成员赋值

约瑟夫环-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;jnext; q=p->next; 用以找到相应的结点,并用指针q指向它,当完成了编号的输出和密码的赋值后,删除q指向的结点,将两个循环适当结合,即可输出正确的结果序列,其中的人数n和初始密码在主函数中确定。 四、上机调试: (1)有2个玩家,初始密码为21; (2)有3个玩家,初始密码为5:

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

《数据结构》课程设计报告书 设计题目:约瑟夫环 专业: 班级: 姓名: 指导教师: 完成日期:

目录 一、问题描述 (1) 二、基本要求 (1) 三、测试数据 (1) 四、算法思想 (2) 五、模块划分 (3) 六、数据结构 (4) 七、源程序 (4) 八、界面设计 (6) 九、运行与测试 (6) 十、总结 (8) 十一、思考与感悟 (9)

课程设计设计报告书 一、问题描述 约瑟夫问题是由古罗马著名的史学家Josephus提出的问题演变而来,所以通常称为Josephus问题。改进约瑟夫问题的描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈, 每人有一个密码(整数),留作其出圈后应报到后出圈。报数方法采用顺时针报数和逆时针报数交替进行,初始密码可任意确定。求最后剩下的人的编号。这个就是约瑟夫环问题的实际场景,后来老师要求我们对要求中的每人所持有的密码以及第一次的报数上限值要用随机数产生。因此约瑟夫环问题如果采用双向循环链表则能很好的解决。循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。p->link=head解决问题的核心步骤:先建立一个具有n个链结点,无头结点的循环链表,然后确定第一个报数人的位置,并不断地从链表中删除链结点,直到链表为空。 二、基本要求 (1)输入的形式和输入值的范围:输入的形式是以数字的形式输入,输入范围为-2147483648~2147483648 (2)输出的形式:字符串形式输出 (3)程序所能达到的功能:达到符合约瑟夫环要求的响应功能。 三、测试数据 进入程序,显示“1.开始游戏0.退出游戏”输入非0数进入游戏,输入0退出游戏。 进入游戏后显示“输入总人数”,输入大于0的整数;若输入错误,则光标处清空,重新输入。 后提示“输入开始人的序号”;范围是大于零,小于总人数的整数,若输入错误,则光标处清空,重新输入。 后提示“输入间隔数字”,范围是任意正整数;若输入错误,则光标处清空,重新输入。 按回车键,显示结果,并重新询问“1.开始游戏0.退出游戏”。

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

******************* 实践教学 ******************* 兰州理工大学 软件职业技术学院 2011年春季学期 算法与数据结构课程设计 题目:约瑟夫环 专业班级: 姓名: 学号: 指导教师: 成绩:

摘要 约瑟夫环问题是典型的线性表的应用实例,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而对于后者则要求应用程序功能完备,易使用等特点。 经过分析,我们使用MICROSOFT公司的Microsoft Visual C++6.0开发工具,利用其提供的各种面向对象的开发工具,尤其是数据窗口这一能方便而简洁操纵数据库的智能化对象,首先在短时间内建立系统应用原型,然后,对初始原型系统进行需求迭代,不断修正和改进,直到形成用户满意的可行系统。 关键词:单循环链表;c语言;约瑟夫环;

序言 数据结构是研究数据元素之间的逻辑关系的一门课程,以及数据元素及其关系在计算机中的存储表示和对这些数据所施加的运算。该课程设计的目的是通过课程设计的综合训练,培养分析和编程等实际动手能力,系统掌握数据结构这门课程的主要内容。 本次课程设计的内容是用单循环链表模拟约瑟夫环问题,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。通过这个设计实例,了解单链表和单循环链表的相同与不同之处,进一步加深对链表结构类型及链表操作的理解。 通过该课程设计,能运用所学知识,能上机解决一些实际问题,了解并初步掌握设计、实现较大程序的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。

双向循环链表list

list是双向循环链表,,每一个元素都知道前面一个元素和后面一个元素。在STL 中,list和vector 一样,是两个常被使用的容器。和vector不一样的是,list不支持 对元素的任意存取。list中提供的成员函数与vector类似,不过list提供对表首元素的操作 push_front、pop_front,这是vector不具备的。禾口vector另一点不同的是,list的迭代器不会存在失效的情况,他不像vector会保留备份空间,在超过容量额度时重新全部分配内存,导致迭代器失效;list没有备份空间的概念,出入一个元素就申请一个元素的空间,所以它的迭代器不会失效。还是举《C++之vector》中的 例子: int data[6]={3,5,7,9,2,4}; list< int> lidata(data, data+6); lidata.push_back(6); list初始化时,申请的空间大小为6,存放下了data中的6个元素,当向lidata插入第7个元素“6”,list申请新的节点单元,插入到list链表中,数据存放结构如图1所示: 插入节点"6拆之后的list 图1 list的存储结构 list每次增加一个元素,不存在重新申请内存的情况,它的成本是恒定的。而vector每当增加关键元素的时候,都需要重新申请新的更大的内存空间,会调用元素的自身的复制构造函数,存在构造成本。在销毁旧内存的时候,会调用析构函数, 存在析构成本。所以在存储复杂类型和大量元素的情况下,list比vector更有优势! List是一个双向链表,双链表既可以向前又向后链接他的元素。

数据结构实验约瑟夫环..

数据结构课程设计题目 1.目的 数据结构是研究数据元素之间的逻辑关系的一门课程,以及数据元素及其关系在计算机中的存储表示和对这些数据所施加的运算。该课程设计的目的是通过课程设计的综合训练,培养分析和编程等实际动手能力,系统掌握数据结构这门课程的主要内容。 2.内容 本次课程设计的内容是用单循环链表模拟约瑟夫环问题,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。通过这个设计实例,了解单链表和单循环链表的相同与不同之处,进一步加深对链表结构类型及链表操作的理解。 约瑟夫环问题的描述是:设编号为1,2,…,n的n个人按顺时针方向围坐一圈,每个人持有一正整数密码。开始时选择一个正整数作为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m时停止报数,报m的人出圈,将他的密码作为新的m值,从他在顺时针方向上的下一个人起重新从1报数。如此下去,直到所有人都出圈为止。令n最大值为100。要求设计一个程序模拟此过程,求出出圈的编号序列。 3.设计: 1)对设计内容进行分析

2)逻辑设计 1、循环链表抽象数据类型定义 typedef struct LNode//定义单循环链表中节点的结构 { int num;//编号 int pwd;//password struct LNode *next;//指向下一结点的指针 }LNode; 2、本程序包含一下几个模块 (1)构造结点模块 LNode *createNode(int m_num,int m_pwd) { 图2 约瑟夫环原理演示图

C语言课程设计报告约瑟夫环胡存夫

C语言课程设计报告约瑟夫环胡存夫

沈阳航空航天大学 课程设计报告 课程设计名称:C语言课程设计课程设计题目:约瑟夫环 院(系):计算机学院 专业:计算机科学与技术班级:3410301 学号: 姓名:胡存夫 指导教师:丁一军

目录 1 课程设计介绍 ......................................................... 错误!未定义书签。 1.1课程设计内容及要求 ........................................... 错误!未定义书签。 1.2系统需求............................................................... 错误!未定义书签。 2 课程设计原理 ......................................................... 错误!未定义书签。 2.1课设题目粗略分析 ............................................... 错误!未定义书签。 2.2.1 功能模块图..................................................... 错误!未定义书签。 2.2.2 流程图分析..................................................... 错误!未定义书签。 3 调试与分析............................................................. 错误!未定义书签。 3.1调试过程............................................................... 错误!未定义书签。参考文献 .................................................................... 错误!未定义书签。附录(关键部分程序清单) ................................... 错误!未定义书签。

数据结构实验 建立双向循环链表以及插入删除操作

实验一 要求:①建立双向循环链表 ②实现链表的插入、删除 运行程序点此处Demo_1.exe 实验程序源代码: #include "stdafx.h" #include #include #define OVERFLOW -2 #define ERROR 0 #define OK 1 typedef int status; //双向循环链表的存储结构 typedef struct DuLNode { int data; int Length; struct DuLNode *prior; struct DuLNode *next; } DuLNode,*DuLinkList; //构建一个空的双向循环链表 void InitList(DuLNode **p) { *p=(DuLNode *)malloc(sizeof(DuLNode)); if(*p) { (*p)->next=(*p)->prior=*p; (*p)->Length=0; } else exit(OVERFLOW); } //双向循环链表的创建 void Create(DuLinkList &L,int n) { //输入n个元素的值,建立带头结点的双线循环链表L DuLinkList p=L,q; int i; for(i=1;i<=n;i++) { q=(DuLinkList)malloc(sizeof(DuLNode)); printf("您该输入第%d个元素的值了:",i); scanf("%d",&q->data);

p->next =q; q->prior=p; q->next=L; L->prior =q; p=q; L->Length ++; } } //查找元素的位置 DuLinkList GetElemP(DuLinkList h,int i) { int j; DuLinkList p=h; for(j=1;j<=i;j++) p=p->next ; return p; } //结点的插入 status Listinsert(DuLNode *m,int i,int e) { //在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长 DuLinkList p,q; if(i<1||i>(m->Length)) // i值不合法 return ERROR; p=GetElemP(m,i); if(!p) return ERROR; q=(DuLinkList)malloc(sizeof(DuLNode)); if(!q) return OVERFLOW; q->data=e; q->prior=p->prior; p->prior->next=q; q->next=p; p->prior=q; m->Length++; printf("您在双向循环链表第%d个位置之前插入了一结点元素:%d\n",i,e); return OK; } //结点的删除 status ListDelete(DuLinkList L,int i) { //删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长

循环双向链表

#include #include "Dlink.h" int main(void) { DLink *L; int i = 0; ElemType e = '0'; //认真体会C语言拷贝传递的思想 InitList(&L); InsElem(L, 'a', 1); InsElem(L, 'b', 2); InsElem(L, 'c', 3); InsElem(L, 'd', 4); InsElem(L, 'e', 5); printf("线性表"); DispList(L); printf("长度:%d/n",GetLength(L)); i = 3; GetElem(L, i, &e); printf("第%d个元素:%c/n", i, e); e = 'a'; printf("元素%c是第%d个元素/n", e, Locate(L, e)); i = 4; printf("删除第%d个元素/n", i); DelElem(L, i); printf("线性表:"); DispList(L); /**/ return 0; } [cpp] view plaincopyprint? #ifndef DLINK #define DLINK typedef char ElemType;

typedef struct node { ElemType data; struct node *prior, *next; }DLink; void InitList(DLink **L); //初始化运算 int GetLength(DLink *L); //求表长运算 int GetElem(DLink *L, int num, ElemType *e); //求线性表中第i个元素运算int Locate(DLink *L, ElemType x); //按值查找运算 int InsElem(DLink *L, ElemType x, int i); //插入节电运算 int DelElem(DLink *L, int num); //删除结点运算 void DispList(DLink *L); //输出线性表 #endif [cpp] view plaincopyprint? #include #include "Dlink.h" #include /************************************************ ** 函数名:void InitList(DLink **L) ** 功能:初始化线性表运算 ** 描述:无 ** 作者:/***/ *************************************************/ void InitList(DLink **L) { *L = (DLink *)malloc(sizeof(DLink)); (*L)->prior = (*L)->next = *L; } /************************************************ ** 函数名:int getLength(DLink *L) ** 功能:获取链表的长度 ** 描述:无 ** 作者:/***/ *************************************************/ int GetLength(DLink *L)

约瑟夫环问题课程设计报告

数据结构 课程设计报告设计课题:约瑟夫问题 院系:计算机科学与技术学院 专业班级:计算机网络技术1102班学生姓名:张利 学号: 1 1 0 8 0 4 0 2 1 1 指导教师:王昱哲

目录 1.需求分析 (3) 1.1问题描述 (3) 1.2功能分析 (4) 2.概要设计 (5) 3.详细设计 (6) 4.调试与操作说明........... 1错误!未定义书签。总结. (16)

一.需求分析 1.1问题描述 约瑟夫环问题描述的是:设编号为1,2,…,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一正整数密码。开始时选择一个正整数作为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m时停止报数,报m的人出圈,将他的密码作为新的m值,从他在顺时针方向上的下一个人起重新从1报数。如此下去,直到所有人都出圈为止。令n最大值为100。要求设计一个程序模拟此过程,求出出圈的编号序列。如下图分析:

1.2功能分析 约瑟夫环问题是一个古老的数学问题,本次课题要求用程序语言的方式解决数学问题。此问题仅使用单循环链表就可以解决此问题。而改进的约瑟夫问题通过运用双向循环链表,同样也能方便地解决。 在建立双向循环链表时,因为约瑟夫环的大小由输入决定。为方便操作,我们将每个结点的数据域的值定为生成结点时的顺序号和每个人持有的密码。进行操作时,用一个指针current 指向当前的结点,指针front 始终指向头结点。然后建立双向循环链表,因为每个人的密码是通过rand()函数随机生成的,所以指定第一个人的顺序号,找到结点,不断地从链表中删除链结点,直到链表剩下最后一个结点,通过一系列的循环就可以解决改进约瑟夫环问题。 图2 约瑟夫环原理演示图

相关文档
相关文档 最新文档