文档库 最新最全的文档下载
当前位置:文档库 › C语言实现约瑟夫环

C语言实现约瑟夫环

C语言实现约瑟夫环
C语言实现约瑟夫环

《约瑟夫环》实验报告

专业:网络工程班级

学号姓名

一、问题描述:

约瑟夫问题的一种描述是:编号为1,2,……,n点的n个人按顺时针方向围坐一个圈,每人持有一个密码。一开始选一个正整数作为报数上限值m,从第一个人开始从顺时针方向自1开始报数,报到m时停止。报到m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始从新从1报数,如此下去,直达所有人出列。

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

测试数据:m的初始值为20;n=7,7个人的密码依次是3,1,7,2,4,8,4,首先m的值为6(正确的出列顺序为6,1,4,7,2,3,5)

二、程序设计的基本思想,原理和算法描述:

采用结构体定义单链表,格式为:struct Lnode

{int number;

int password;

struct Lnode*next;

}Lnode,*p,*q,*head;

其中number是人的排列序号,password是各人所持有的密码值,next是节点指针。Lnode是节点变量,p、q是节点,head是头指针。

程序的代码:定义变量n,i,m,j

输入人的数量n

If n<=0或n>30

重新输入n值

当0

建立单链表并且输入各人的密码值p->password

尾指针指向头指针,形成循环链表

输入初始报数上限值m

当1<=j<=n时

循环找出报m的节点p

输出报m节点的编号p->number

将p->password赋给m值

删除此节点

结束

三、源程序及注释:

#include

#include

struct Lnode/*定义链表*/

{int number;

int password;

struct Lnode*next;

}Lnode,*p,*q,*head;

int main(void)

{int n;/*n个人*/

int i;

int m;/*初始报数上限值*/

int j;

printf("please enter the number of people n:");/*输入测试人的数量*/ scanf("%d",&n);

loop:if(n<=0||n>30)/*检验n是否满足要求,如不满足重新输入n值*/ {printf("\n n is erorr!\n\n");

printf("please enter the number of people again n:");

scanf("%d",&n);

goto loop;

}

for(i=1;i<=n;i++)/*建立单链表*/

{if(i==1)

{head=p=(struct Lnode*)malloc(sizeof(struct Lnode));

}

else

{q=(struct Lnode*)malloc(sizeof(struct Lnode));

p->next=q;

p=q;

}

printf("please enter the%d people's password:",i);/*输入每个人所持有的密码值*/ scanf("%d",&(p->password));

p->number=i;

}

p->next=head;/*形成循环链表*/

p=head;

printf("please enter the number m:");

scanf("%d",&m);

printf("The password is:\n");

for(j=1;j<=n;j++)/*输出各人的编号*/

{for(i=1;inext);

m=p->password;

printf("%d",p->number);

p->number=p->next->number;/*删除报m的节点*/

p->password=p->next->password;

q=p->next;

p->next=p->next->next;

free(q);

}

printf("\n\n");

system("pause");/*等待按任意键退出*/

}

四、运行输出结果:

测试的数据:n为7,m的初值为20,密码:3、1、7、2、4、8、4,正确的结果应为:6、1、4、7、2、3、5。

五、调试分析

本次实习作业难度较低,没有太大的困难。主要是练习使用单项循环链表。

六、实验小结

1、通过本次上机实践,对链表存储结构有了更深的理解和把握,以及应用链表的知识解

决和分析问题的能力有了新的提高.

2、通过上机实践,掌握了用高级语言实现算法的基本步骤和方法。

3、通过本次实验,提高了理论和实际相结合的能力。

c语言实现约瑟夫环问题

(一)基本问题 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 个) inext; 删除p 结点的后一结点q q=p->next; p->next=q->next; *L = p->next; 报出位置后Delete q; 计数器i++; 运行流程图

约瑟夫问题

一问题描述 1 题目内容:约瑟夫(Joseph)问题的一种描述是:编号为1,2,..., n的n 个人按顺时针方向围坐一圈, 每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值。试设计一个程序求出出列顺序。 2 基本要求:利用单项循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。 3 测试数据:m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4(正确的出列顺序应为6,1,4,7,2,3,5)。 二需求分析 程序运行后,首先要求用户指定初始报数上限值,然后读取个人的密码。输入数据:建立输入处理输入数据,输入m的初值,n ,输入每个人的密码,建立单循环链表。输出形式:建立一个输出函数,将正确的输出序列 三概要设计 利用单项循环链表存储结构模拟此过程 1 循环链表的抽象数据类型 循环链表是单链表的一种变化形式,把单链表的最后一个节点的next指针指向第一个节点,整个链表就形成了一个环。

2 循环链表的基本操作(仅列出用在本程序的) creat(n) 操作结果:构造一个长度为n的无头节点的循环链表,并返回指向最后一个节点的指针 find(m,s) 初始条件:循环链表存在 操作结果:找到当前元素(即s)后面第m个元素 print(&m,&n,&s) 初始条件:循环链表存在 操作结果:从s中删除约舍夫问题中下一个被删除的元素,并将此元素显示在屏幕上 3 本程序包括4个模块: 主程序模块; 创建循环链表模块; 找节点模块; 删节点模块; 各模块调用关系如下图所示:

顺序表实现约瑟夫环的问题c语言

计算机科学与工程学院 《算法与数据结构》试验报告[一] 专业班级10级计算机工程02 试验地点计算机大楼计工教研室学生学号1005080222 指导教师蔡琼 学生姓名肖宇博试验时间2012-2-29 试验项目算法与数据结构 试验类别基础性()设计性()综合性(√)其它() 试验目的及要求(1)掌握用VC++上机调试线性表的基本方法;(2)掌握顺序表的存储结构以及基本运算的实现。 成绩评定表 类别评分标准分值得分合计 上机表现积极出勤、遵守纪律 主动完成设计任务 30分 程序与报告程序代码规范、功能正确 报告详实完整、体现收获 70分

备注: 评阅教师: 日期:年月日 试验内容 一、实验目的和要求 1、实验目的: (1)掌握用VC++上机调试线性表的基本方法; (2)掌握顺序表的存储结构以及基本运算的实现。 2、实验内容 约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针 方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的 下一个人开始重新从1报数,报到m时停止并且报m的人出列。如 此下去,直到所有人全部出列为止。要求设计一个程序模拟此过程, 对任意给定的m和n,求出出列编号序列。 3、实验要求:用顺序表实现。 二、设计分析 根据实验要求,采用顺序表来完成本次实验。 实验中定义了两个顺序表,一个用来存储n个人的序号,另一个用来存储n个人的出队顺序及序号。 程序中充分考虑了如果出队的元素大于队列的元素个数时应该有的情况,如果出现这样的错误就提示!否则继续出队! 三、源程序代码 #include #include #define MAXSIZE 10 // 宏替换最大值 typedef struct { int data[MAXSIZE]; int length; }Sqlist; void CreatList(Sqlist *&L,int a[],int n) //创建顺序表 { L=(Sqlist *)malloc(sizeof(Sqlist));

数据结构经典题目及c语言代码

《数据结构》课程设计题目 (程序实现采用C语言) 题目1:猴子选王(学时:3) 一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。 要求:m及n要求从键盘输入,存储方式采用向量及链表两种方式实现该问题求解。 //链表 #include #include // 链表节点 typedef struct _RingNode { int pos; struct _RingNode *next; }RingNode, *RingNodePtr; // 创建约瑟夫环,pHead:链表头指针,count:链表元素个数 void CreateRing(RingNodePtr pHead, int count) { RingNodePtr pCurr = NULL, pPrev = NULL; int i = 1; pPrev = pHead; while(--count > 0)

{ pCurr = (RingNodePtr)malloc(sizeof(RingNode)); i++; pCurr->pos = i; pPrev->next = pCurr; pPrev = pCurr; } pCurr->next = pHead; // 构成环状链表 } void KickFromRing(RingNodePtr pHead, int n) { RingNodePtr pCurr, pPrev; int i = 1; // 计数 pCurr = pPrev = pHead; while(pCurr != NULL) { if (i == n) { // 踢出环 printf("\n%d", pCurr->pos); // 显示出圈循序 pPrev->next = pCurr->next; free(pCurr); pCurr = pPrev->next; i = 1; } pPrev = pCurr;

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

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

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

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

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

数据结构课程设计题目 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语言实现约瑟夫环

《约瑟夫环》实验报告 专业:网络工程班级 学号姓名 一、问题描述: 约瑟夫问题的一种描述是:编号为1,2,……,n点的n个人按顺时针方向围坐一个圈,每人持有一个密码。一开始选一个正整数作为报数上限值m,从第一个人开始从顺时针方向自1开始报数,报到m时停止。报到m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始从新从1报数,如此下去,直达所有人出列。 基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序输出各人的编号。 测试数据:m的初始值为20;n=7,7个人的密码依次是3,1,7,2,4,8,4,首先m的值为6(正确的出列顺序为6,1,4,7,2,3,5) 二、程序设计的基本思想,原理和算法描述: 采用结构体定义单链表,格式为:struct Lnode {int number; int password; struct Lnode*next; }Lnode,*p,*q,*head; 其中number是人的排列序号,password是各人所持有的密码值,next是节点指针。Lnode是节点变量,p、q是节点,head是头指针。 程序的代码:定义变量n,i,m,j 输入人的数量n If n<=0或n>30 重新输入n值 当0password 尾指针指向头指针,形成循环链表 输入初始报数上限值m 当1<=j<=n时 循环找出报m的节点p 输出报m节点的编号p->number 将p->password赋给m值 删除此节点 结束 三、源程序及注释: #include #include struct Lnode/*定义链表*/ {int number;

约瑟夫环问题源代码(C语言)

约瑟夫环问题如下:已知n 个人(n>=1)围桌一园桌周围,从1开始顺序编号。从序号为1的人开始报数,顺时针数到m 的那个人出列。他的下一个人又从1开始报数,数到m 的那个人又出列。依此规则重复下去,直到所有人全部出列。求解最后一个出列的人的编号。 本次实验是以顺序表求解约瑟夫环问题,程序流程图及程序运行结果如下: 程序代码如下: #include #include #include 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() //主函数 { system("color 75"); //设置颜色以美观 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<<"尾指针异常!"<>k; if(k<1||k>n){cout<<"请输入1-"<

约瑟夫问题的C语言算法(循环链表)

算法:n个人围成一圈,每个人都有一个互不相同的密码,该密码是一个整数值,选择一个人作为起点,然后顺时针从1到k(k为起始点手中的密码值)数数。数到k的人退出圈子,然后从下一个人开始继续从1到j(j为刚退出圈子人的密码数)数数,数到j的人退出圈子。重复上述操作,直到最后一人 代码如下: # include # include //free(),malloc()所在库文件 # define n 9 //数字个数 # define overflow 0 //判断溢出情况 int keyw[n]={4,7,5,9,3,2,6,1,8}; //欲处理数的数组 typedef struct lnode //声明结构体,包括两个成员,一个是数值,另一个是指向下个结点的指针 { int keyword; struct lnode *next; }lnode,* linklist; void joseph(linklist p,int m,int x) //定义约瑟夫环函数:p为循环列表头结点,m 为初始值,x为数组长度 { linklist q; //声明变量 int i; if(x==0)return; q=p; m%=x; if(m==0)m=x; for(i=1;i<=m;i++) //找到下一个结点 { p=q; q=p->next; } p->next=q->next; i=q->keyword; printf("%5d",q->keyword); free(q); joseph(p,i,x-1); //递归调用 } int main() { int i,m; linklist lhead,p,q;

顺序表实现约瑟夫环的问题C语言

顺序表实现约瑟夫环的问题C语言 计算机科学与工程学院 《算法与数据结构》试验报告[一] 10级计算机工程02计算机大楼计工教研专业班级试验地点室学生学号1005080222 指导教师蔡琼学生姓名肖宇博试验时间 2012-2-29 试验项目算法与数据结构 试验类别基础性() 设计性() 综合性(?) 其它( ) (1)掌握用VC++上机调试线性表的基本方法; 试(2)掌握顺序表的存储结构以及基本运算的实现。验 目的求及 要 成绩评定表 类别评分标准分值得分合计 积极出勤、遵守纪律 上机表现 30分 主动完成设计任务 程序代码规范、功能正确 程序与报告 70分 报告详实完整、体现收获 计算机科学与工程学院 备注: 评阅教师:

日期: 年月日 试验内容 一、实验目的和要求 1、实验目的: (1)掌握用VC++上机调试线性表的基本方法; (2)掌握顺序表的存储结构以及基本运算的实现。 2、实验内容 约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺 时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针 方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的下 一个人开始重新从1报数,报到m时停止并且报m的人出列。如此下 去,直到所有人全部出列为止。要求设计一个程序模拟此过程,对 任意给定的m和n,求出出列编号序列。 3、实验要求:用顺序表实现。 二、设计分析 根据实验要求,采用顺序表来完成本次实验。 实验中定义了两个顺序表,一个用来存储n个人的序号,另一个用来存储n个人的出队顺序及序号。 程序中充分考虑了如果出队的元素大于队列的元素个数时应该有的情况,如果出现这样的错误就提示~否则继续出队~ 三、源程序代码 #include #include #define MAXSIZE 10 // 宏替换最大值

c语言实现约瑟夫环问题解析

(一)基本问题 1.问题描述 设有编号为1,2,…,n的n(n>0)个人围成一个圈,每个人持有一个密码m。从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m 时停止报数,报m的出圈,……,如此下去,直到所有人全部出圈为止。当任意给定n和m后,设计算法求n个人出圈的次序。建立模型,确定存储结构。对任意n个人,密码为m,实现约瑟夫环问题。 2.数据结构设计 首先,设计实现约瑟夫环问题的存储结构。由于约瑟夫环问题本身具有循环性质,考虑采用循环链表,为了统一对表中任意结点的操作,循环链表不带头结点。将循环链表的结点定义为如下结构类型: struct Node { int data; Node *next; }; 其次,建立一个不带头结点的循环链表并由头指针first指示 3.算法设计 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-> 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个) 当inext; 删除p结点的后一结点q q=p->next; p->next=q->next; *L = p->next; 报出位置后Delete q; 计数器i++; 运行流程图

约瑟夫环C语言的实现验证报告

约瑟夫环 姓名 学号 系别信息与电子系 班级计算 填写日期 2010年10月30

一.问题描述 约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。 二.基本要求 利用利用顺序表存储结构及单向循环链表存储结构模拟约瑟夫环,按照出列的顺序印出各人的编号 三.测试数据 m的上限为20,初值为6; (1) 对于n=7,7个人的密码依次为:3,1,7,2,4,8,4进行测试。 (2) 对于从键盘输入的n和n个人的密码进行测试。

四.用数组实现约瑟夫环 程序代码: #include void main() { int num[100]; int m,n,i,k=0,s=0; int *p=num; printf("输入初始密码和人数n \n"); scanf("%d%d",&m,&n); printf("个人密码\n"); for(i=1;i<=n;i++) scanf("%d",&num[i]); i=1; while(s<=(n-1)) //当未退出人数(s)大于等于一时执行循环体{ if(*(p+i)!=0) k++; if(k==m) { printf("%d ",i); m=*(p+i); *(p+i)=0; // 对退出的人编号置零 k=0; s++; } i++; if(i==(n+1)) //当循环到最后一位时返回到第一位 i=1; } } 测试数据结果:

约瑟夫环实验报告

数据结构课程设计报告 题目:约瑟夫环实验 班级: 成员: 指导教师: 完成日期:

目录: 实习报告要求 (2) 约瑟夫环实验描述 (3) 课程设计报告正文 (4) 一.需求分析 (4) 二.概要设计 (4) 三.详细设计 (6) 1.各模块关键代码及算法的解释: (6) 2.函数的调用关系图 (8) 四.调试分析 (11) 五.用户使用说明 (12) 六.测试结果 (13) 七.小结 (3) 八.附录,带注释的源程序 (4)

实习报告要求 实习报告的开头应给出题目、班级、姓名、学号和完成日期,并包括以下七个内容: 1. 需求分析 以无歧义的陈述说明程序设计的任务,强调的是程序要做什么?明确规定: (1) 输入的形式和输入值的范围; (2) 输出的形式; (3) 程序所能达到的功能; (4) 测试数据:包括正确的输入及其输出结果和含有错误的输入及其输出结果。 2. 概要设计 说明本程序中用到的所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次(调用)关系。 3. 详细设计 实现概要设计中定义的所有数据类型,对每个操作只需要写出伪码算法;对主程序和其他模块也都需要写出伪码算法(伪码算法达到的详细程度建议为:按照伪码算法可以在计算机键盘直接输入高级程序设计语言程序);画出函数的调用关系图。 4. 调试分析 内容包括: (1)调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析; (2)算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的分析)和改进设想; (3)经验和体会等。 5. 用户使用说明 说明如何使用你编写的程序,详细列出每一步的操作步骤。 6. 测试结果 列出你的测试结果,包括输入和输出。这里的测试数据应该完整和严格,最好多于需求分析中所列。 7. 附录 带注释的源程序。可以只列出程序文件名的清单。 实习报告的各种文档资料,如:上述中的前三部分要在程序开发的过程中逐渐充实形成,而不是最后补写(当然也可以应该最后用实验报告纸誉清或打印)。

约 瑟 夫 环 问 题 的 三 种 解 法

约瑟夫环解法大全(C语言版) 前言:约瑟夫环不愧是一道经典的算法题,原来也经常看到,但一直没有动手编码研究。最近又被同学提起这个问题,就研究了一下,发现这个问题可以挖掘的东西有很多,怪不得一直是面试的热门问题。 解法一,使用链表模拟: 使用链成环的单链表完全模拟这个计数淘汰的过程,计数到要淘汰的结点时,直接删除该结点。 typedef struct NODE{ struct NODE* next; int cycle0(int n, int m){ -- 使用链表实现 PN* head = (PN*)malloc(sizeof(PN)); head-num = 0; head-next = NULL; PN* tail = head; -- 恒指向链表尾 for(int i = 1; i n; ++i){ tail-next = (PN*)malloc(sizeof(PN)); tail = tail-next; tail-num = i; tail-next = NULL; tail-next = head; -- 链成环 PN* p = head;

int j = 0; -- 报数器 while(p-next != p){ -- 如果 p 的下一个结点指向自己,说明环中只剩一个结点 if(j == m-2){ -- 每次报到 m-2 删除当前 p 指向结点的下一个结点 PN* q = p-next; p-next = q-next; free(q); -- 释放内存 p = p-next; p = p-next; return p-num; 解法二,使用数组模拟: 数组模拟法用数组下标对应人的编号。最简单直白的模拟方式,就是使用数组值来表示存活或者淘汰,一般我们用 0 和 1 来表示,如果数组元素值对应淘汰,则在计数时跳过该元素。 int cycle1(int n, int m){ -- 使用数组实现 1 代表活 0 代表淘汰(反过来也可以) int a[n]; for(int i = 0; i n; ++i){ a[i] = 1; int i = 0, j = 0, count = 0; while(count n-1){

约瑟夫环

实习报告 题目 : 实现一个约瑟夫环程序 班级: 05计(1)姓名:学号: 完成日期:2007.10.12 一、需求分析 1.本演示程序中,利用单向循环链表存储结构存储约瑟夫环数据(即n个人的编号和密码)。 2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示"提示信息"之后,由用户在键盘上输入演示程序中需要输入的数据,运算结果显示在其后。 3.程序执行的命令包括: 1)构造单向循环链表;2)进行数值的输入,并作判断分析;3)约瑟夫算法的实现与结果输出;4)结束。 4.测试数据 m 的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,(正确的出列顺序为6,1,4,7,2,1,3,5)。 二、概要设计 1.单向循环链表的抽象数据类型定义为: ADT List{ 数据对象:D={ai | ai?正整数,I=1,2,......,n,n≥0} 数据关系:R1={< ai-1,ai > |,ai-1,ai?D,I=1,2,......,n} 基本操作: Init List(&L) 操作结果:构造一个空的线性表L。 List Insert(&L,i,e) 初始条件:线性表L已存在,1≤i≤List Length(L)+1. 操作结果:在L中第i个位置之前插入新的数据元素e,L长度加1。 List Delete(&L,i,&e) 初始条件:线性表L存在非空,1≤i≤List Length(L). 操作结果:删除L的第i个元素,并用e返回其值,L长度减1。 2.程序包含四个模块: 1)主程序模块: void main( ) { 初始化; for(; ;) {} while(命令=开始)

简单约瑟夫环问题C语言解答

简单约瑟夫环问题C语言解答 问题:有N个小孩围成一圈并依次编号,教师指定从第M个小孩开始报数,报到第S个小孩即令其出列。然后从下一个孩子继续报数,数到第S个小孩又令其出列,如此直到所有的孩子都出列。求小孩出列的先后顺序。 C语言解答: #include #include //声明循环链表结构体 typedef struct LNode { int num; struct LNode *next; }LNode; //创建结点 LNode *Create_node(int Lnum) { LNode *Lp; Lp=(LNode *)malloc(sizeof(LNode)); Lp->num=Lnum; Lp->next=NULL; return Lp; } //创建循环链表 LNode *Create_Linklist(LNode *pHead, int Lsum) { int k; LNode *p, *temp; for(k=1;k<=Lsum;k++) { p=Create_node(k); //如果链表为空,创建链表第一个结点,其next指针指向自身 if(pHead==NULL) { temp=p; pHead=p; temp->next=pHead; } //否则,执行插入节点操作 else { p->next=temp->next; temp->next=p; temp=p; }

} //测试是否生成循环链表成功! /* p=pHead; k=1; while(p->next!=pHead) { printf("第%d个小孩的编号为:%d\n",k,p->num); p=p->next; k++; } printf("第%d个小孩的编号为:%d\n",k,p->num); */ return pHead; } //执行出列操作 void Delete_Linklist(LNode *pHead,int Lstart, int Ldel) { int i,count=1; LNode *p, *temp; p=pHead; //找到第M个孩子所在的位置 for(i=1;inext; //只剩1个结点时终止循环 while(p->next!=p) { //找到要出列的孩子的位置 for(i=1;inext; } //执行出列操作 temp->next=p->next; printf("第%d个出列的小孩的编号为:%d\n",count,p->num); free(p); count++; //出列者的下一个孩子作为新的第一个报数者 p=temp->next; } printf("第%d个出列的小孩的编号为:%d\n",count,p->num); free(p); //所有人均出列,头结点释放后赋空值,避免出现悬垂指针 pHead=NULL; } int main()

C语言实现约瑟夫环源代码

约瑟夫环源代码: #include typedef struct Node { int data; struct Node *next; }*Pointer; Pointer p,q,s Pointer Initlink(Pointer &head) { head=new Node; head->next=head; return(head); } void Creatlink(Pointer &head,int n) { p=head; if(n>=2) { for(int i=1;i<=n-1;i++) { p->data=i; s=new Node; p->next=s; p=s; } p->data=n; p->next=head; } else { p->data=1; p->next=head; } } int Length(Pointer &head) { int j=1; p=head; while(p->next!=head) { p=p->next; j++; }

return(j); } Pointer Find(Pointer &head,int i) { p=head; if(i>1) { for(int t=1;t<=i-1;t++) { p=p->next; } } else { p=head; } return p; } void Delete(Pointer &head,int m) { if(m>1) { p=Find(head,m-1); q=p->next; p->next=p->next->next; delete(q); } else { p=Find(head,Length(head)); p->next=p->next->next; } } void main() { int n,m; Pointer head,s; Initlink(head); s=head; printf("请输入约瑟夫环所含数据总量n:"); scanf("%d",&n); printf("\n"); Creatlink(head,n); printf("请输入需要循环的次数m:");

数据结构经典题目及c语言代码

数据结构经典题目及c 语言代码 公司内部编号:(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-

《数据结构》课程设计题目 (程序实现采用C语言) 题目1:猴子选王(学时:3) 一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。 要求:m及n要求从键盘输入,存储方式采用向量及链表两种方式实现该问题求解。 //链表 #include #include // 链表节点 typedef struct _RingNode { int pos; struct _RingNode *next; }RingNode, *RingNodePtr; // 创建约瑟夫环,pHead:链表头指针,count:链表元素个数

void CreateRing(RingNodePtr pHead, int count) { RingNodePtr pCurr = NULL, pPrev = NULL; int i = 1; pPrev = pHead; while(--count > 0) { pCurr = (RingNodePtr)malloc(sizeof(RingNode)); i++; pCurr->pos = i; pPrev->next = pCurr; pPrev = pCurr; } pCurr->next = pHead; // 构成环状链表 } void KickFromRing(RingNodePtr pHead, int n) { RingNodePtr pCurr, pPrev;

C语言数组实现约瑟夫环问题(源程序)

设有SIZE=30个人围坐一圈,从某个人开始报数,数到N=7的人出列,接着下从下一个人开始从新报数,数到N=7的人又出列, 直到所有的人出列为止。输出出队列的顺序。 */ #include #define SIZE 30 void goout(int p[],int po[],int n) { int i; int j=0; int k=0; int count; for(i=0;i

printf("\nOUTPUT s:\n"); for(i=0;i

约瑟夫问题 完整C程序代码

1)内容:约瑟夫(Joseph)问题的一种描述是:编号为1,2,..., n 的n 个人按顺时针方向围坐一圈, 每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值,再从下个人开始新一轮报数,如此反复,直到剩下最后一人则为获胜者。试设计一个程序求出出列顺序。 2)要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。3) 测试数据: n=7,7 个人的密码依次为:3,1,7,2,4,8,4 。m的初值为20,则正确的出列顺序应为6,1,4,7,2,3,5。 完整代码: #include #include struct person { int num; int order; struct person *next; }; static struct person *head=NULL; struct person *CreatList(void) { struct person *rear; struct person *p; int k=0; while(1) { p=(struct person*)malloc(sizeof(struct person)); p->order=++k; printf("\n请输入一个人所持的密码,输入0则建表结束:"); scanf("%d",&p->num); if(p->num==0)break; if(head==NULL) head=p; else rear->next=p; rear=p; } if(rear!=NULL) rear->next=head; printf("\n建表结束\n"); return head; }

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