C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析
尝试表达
本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这个游戏;按这样的规则,剩下一个人,游戏就结束,这个人就为赢家。(读者可以试着表达,不认同,直接忽略)
抽象分析
这个人就是一个数据个体,数据结点,数据元素。上面产生的数据结构为:单方向循环的链。可以用链表实现,也可以用数组来实现。
链表到数组的迁移
|
人(数据元素、 数据结点、数据个体) |
结点关系 (结构关系 结点移动) |
范型“指针”定义 :能够定位到下一个结点(变) |
“指针“ |
移到下一个结点 拿到下一个结点的”指针“即可,一般都有作“移动”变量,移动变量变,就相当于移动。 |
删除结点 |
|
|
数组 |
连续的数组元素(基本数据类型,机构体) |
数组元素里面保存有下个结点元素的数组元素下标position。 |
arrayname固定的,只要给出position,就可以算是定位到数组元素 |
≈poisiton [] |
move |
元素内容 (数组的大小固定) |
|
链表 |
离散的链表结点(结构体) |
结构体里面保存有下一个结点的指针 |
poiter直接定位到结点,在结合常员变量,就可以拿到数据 |
=poiter -> |
move |
销毁 |
画图分析:

代码实现:
#include<stdio.h>
#include<stdlib.h> /*Function:遍历数组实现的约瑟夫环。traverse_joseph_circle_array
*param:int[] array,int tail
*return: void
* 假设是用数组实现的约瑟夫环链一定存在。
* */
void traverse_joseph_circle_array (int array[], int tail ){
//数组保存的是下个结点的“指针”,只不过这个指针要通过array才能够拿到结点的元素,因为array是固定的,只要变换指针就能够变换结点。
int move= array [tail] ;//从头开始遍历
do{
printf ("%d ;",move) ;//数组的元素位置(下标号)就代表这个结点,链表是通过结点里面的元素,
move = array[move];
}while ( move != array [tail]);
printf("\n");
}
/*Function:约瑟夫环问题的数组实现。eliminate_array
*param:int[]array,int tail, int step
*return: void
* */
void eliminate_array1 (int array[], int tail ,int step ){
int move = tail ;
int save_previous = move ;
int count = ;
while(move != array[move]){
save_previous = move ;
move = array [move];
if(++ count == step){ //数数
array[save_previous] = array[move] ;//重构链
if( tail == move) tail = save_previous;//销毁前,判断要不要更新新约瑟夫环
printf("当前要删除的结点:%d \n",move);//销毁前告知用户
array[move]= - ;//销毁
printf("当前的约瑟夫环为:\n") ;
traverse_joseph_circle_array (array,tail);
count = ;
move = save_previous ; }
}
}
/*Function:约瑟夫环问题的数组实现。eliminate_array
*param:int[]array,int tail, int step
*return: void
* */
void eliminate_array2 (int array[], int tail ,int step ){
int move = tail ;
int save_previous = move ;
int count = ;
//每执行一此循环,删除一个结点。
while (move != array[move]){ save_previous = move ;
move = array[move]; // 移动到要删除的结点
for (count = ; count < step - ; count++){
move = array[move] ;
}
//删除结点,重构约瑟夫环,更新tail
array[save_previous] = array[move] ;//重构链
if( tail == move) tail = save_previous;//update tail
printf("当前要删除的结点:%d \n",move);//销毁前告知用户
array[move]= - ;//销毁
printf("当前的约瑟夫环为:\n") ;
traverse_joseph_circle_array (array,tail); //移动回消除结点的上一个结点,回到初态,即将进行下一轮的游戏。
count = ;
move = save_previous ; } }
int main(){
//创建有6个结点的约瑟夫环int array[6];
int array[];
int length = sizeof(array)/sizeof(int);
int ctl ;
for (ctl = ; ctl < length - ;ctl ++){
array[ctl] = ctl + ;
}
array [length -] = ;
traverse_joseph_circle_array(array,length-);
int tail = length -;
//eliminate_array1(array ,tail ,3) ;
eliminate_array2(array ,tail ,) ;
return ;
}
结果:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ; ; ; ; ; ; ; ; ; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ; ; ; ; ; ; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ; ; ; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ; ; ; ;
当前要删除的结点:
当前的约瑟夫环为:
; ;
当前要删除的结点:
当前的约瑟夫环为:
;
时间复杂度分析:
本人推荐使用第二种算法来作,对于时间复杂度,要通过逻辑思考,要删除(n-1)个结点,循环执行(n-1)次,内循环执行k=step 次,这个k可能很大;还有在外循环,与内循环无关的,必须执行的某些语句,执行次数为c,表达式为:(n-1)(k+c)=nk +nc -k -c ,表达为:n*k - c0 * n - c1 *k ,大O表达为:O(nk)
注意:感谢麦子学院出的精品课程。本人由于学业繁多,精力有限,水平不足,难免不出问题,请多多包涵,发现什么错漏,有什么建议,请留言私信qq:632929757。
C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析的更多相关文章
- j使用数组实现约瑟夫环 java
我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化 ...
- C语言链表实现约瑟夫环问题
需求表达:略 分析: 实现: #include<stdio.h> #include<stdlib.h> typedef struct node { int payload ; ...
- 约瑟夫环问题-循环链表VS数组
2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...
- 通过例子进阶学习C++(六)你真的能写出约瑟夫环么
本文是通过例子学习C++的第六篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然后从出局的下一个人重新 ...
- 约瑟夫环的C语言数组实现
约瑟夫环问题的具体描述是:设有编号为1,2,……,n的n个(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,才从他的下一个人起重新报数,报到m时停止报数,报m的出圈, ...
- 约瑟夫环(N个人围桌,C语言,数据结构)
约瑟夫环问题(C语言.数据结构版) 一.问题描述 N个人围城一桌(首位相连),约定从1报数,报到数为k的人出局,然后下一位又从1开始报,以此类推.最后留下的人获胜.(有很多类似问题,如猴子选代王等等, ...
- 约瑟夫环问题-Java数组解决
约瑟夫环问题说的是,n个人围成一圈,从第k个人开始沿着一个方向报数,报到第m个人时,第m个人出列,从紧挨着的下一个人(未出列)开始,求整个环中人的出列顺序.下面是我用java实现的解决方法. clas ...
- 约瑟夫环问题 --链表 C语言
总共有m个人在圆桌上,依次报名,数到第n个数的人退出圆桌,下一个由退出人下一个开始继续报名,循环直到最后一个停止将编号输出 #include <stdio.h>#include <s ...
- 数据结构7: 循环链表(约瑟夫环)的建立及C语言实现
链表的使用,还可以把链表的两头连接,形成了一个环状链表,称为循环链表. 和它名字的表意一样,只需要将表中最后一个结点的指针指向头结点,就形成了一个环. 图1 循环链表 循环链表和动态链表相比,唯一的不 ...
随机推荐
- 如何用Dummy实例执行数据库的还原和恢复
今天实验了一下,如何在所有文件,包括数据文件,在线日志文件,控制文件都丢失的情况下,利用RMAN备份恢复和还原数据库.该实验的重点是用到了Dummy实例. 具体步骤如下: 备份数据库 [oracle@ ...
- OWIN 中 K Commands(OwinHost.exe)与 Microsoft.AspNet.Hosting 的角色问题
问题详情:K Commands(OwinHost.exe)是不是 OWIN 中的 Host 角色?如果是,那 Microsoft.AspNet.Hosting 对应的是 OWIN 中的哪个角色? OW ...
- android 在使用ViewAnimationUtils.createCircularReveal()无法兼容低版本的情况下,另行实现圆形scale动画
ViewAnimationUtils.createCircularReveal()的简介: ViewAnimationUtils.createCircularReveal()是安卓5.0才引入的,快速 ...
- 相克军_Oracle体系_随堂笔记014-锁 latch,lock
1.Oracle锁类型 2.行级锁:DML语句 3.表级锁:TM 4.锁的兼容性 5.加锁语句以及锁的释放 6.锁相关视图 7.死锁 1.Oracle锁类型 锁的作用 latch锁:chain ...
- 理解领域模型Domain Model
定义 业务对象模型(也叫领域模型 domain model)是描述业务用例实现的对象模型.它是对业务角色和业务实体之间应该如何联系和协作以执行业务的一种抽象.业务对象模型从业务角色内部的观点定义了业务 ...
- CSS padding margin border属性详解
图解CSS padding.margin.border属性W3C组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落.列表.标题.图片以及层. ...
- 使用 PowerShell 自动化 CloudServices 发布
在软件的开发过程中,自动化的编译和部署能够带来很多的优势.如果可以通过一个脚本实现软件的自动化部署,那么就可以节省大量的时间去做其它事情. 下面介绍如何将云应用程序通过 PowerShell 自动发布 ...
- 写出好的 commit message
为何要关注提交信息 加快Reviewing Code的过程 帮助我们写好release note 5年后帮你快速想起来某个分支,tag或者 commit增加了什么功能,改变了哪些代码 让其他的开发者在 ...
- Web API与文件操作
前段时间,一直有练习ASP.NET MVC与Web API交互,接下来,Insus.NET再做一些相关的练习,Web API与文件操作,如POST文件至Web API,更新或是删除等. 不管怎样,先在 ...
- 芒果TV招聘研发工程师(JAVA PYTHON),地点长沙
长沙芒果TV招聘高级 JAVA Python 工程师,工作地点:湖南广电 有兴趣的邮件0xmalloc@gmail.com; zealotyin@qq.com 公司有一大批从北京上海一线互联网企业 ...