尝试表达

本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这个游戏;按这样的规则,剩下一个人,游戏就结束,这个人就为赢家。(读者可以试着表达,不认同,直接忽略)

抽象分析

这个人就是一个数据个体,数据结点,数据元素。上面产生的数据结构为:单方向循环的链。可以用链表实现,也可以用数组来实现。

链表到数组的迁移

人(数据元素、

数据结点、数据个体)

结点关系

(结构关系

结点移动)

范型“指针”定义

:能够定位到下一个结点(变)

“指针“

移到下一个结点

拿到下一个结点的”指针“即可,一般都有作“移动”变量,移动变量变,就相当于移动。

删除结点

数组

连续的数组元素(基本数据类型,机构体)

数组元素里面保存有下个结点元素的数组元素下标position。

arrayname固定的,只要给出position,就可以算是定位到数组元素

≈poisiton

[]

move
=array[move]

元素内容
=
-1

(数组的大小固定)

链表

离散的链表结点(结构体)

结构体里面保存有下一个结点的指针
node*
next

poiter直接定位到结点,在结合常员变量,就可以拿到数据

=poiter

->

move
= move -> next

销毁

画图分析:

代码实现:

#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语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析的更多相关文章

  1. j使用数组实现约瑟夫环 java

    我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化 ...

  2. C语言链表实现约瑟夫环问题

    需求表达:略 分析: 实现: #include<stdio.h> #include<stdlib.h> typedef struct node { int payload ; ...

  3. 约瑟夫环问题-循环链表VS数组

    2013-08-18 21:27:50 循环链表.数组解决约瑟夫环问题的比较 注意几点: 循环链表的建立不难,在删除循环链表中元素时,用pCur->next != pCur判断结束: 每一轮计数 ...

  4. 通过例子进阶学习C++(六)你真的能写出约瑟夫环么

    本文是通过例子学习C++的第六篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然后从出局的下一个人重新 ...

  5. 约瑟夫环的C语言数组实现

    约瑟夫环问题的具体描述是:设有编号为1,2,……,n的n个(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,才从他的下一个人起重新报数,报到m时停止报数,报m的出圈, ...

  6. 约瑟夫环(N个人围桌,C语言,数据结构)

    约瑟夫环问题(C语言.数据结构版) 一.问题描述 N个人围城一桌(首位相连),约定从1报数,报到数为k的人出局,然后下一位又从1开始报,以此类推.最后留下的人获胜.(有很多类似问题,如猴子选代王等等, ...

  7. 约瑟夫环问题-Java数组解决

    约瑟夫环问题说的是,n个人围成一圈,从第k个人开始沿着一个方向报数,报到第m个人时,第m个人出列,从紧挨着的下一个人(未出列)开始,求整个环中人的出列顺序.下面是我用java实现的解决方法. clas ...

  8. 约瑟夫环问题 --链表 C语言

    总共有m个人在圆桌上,依次报名,数到第n个数的人退出圆桌,下一个由退出人下一个开始继续报名,循环直到最后一个停止将编号输出 #include <stdio.h>#include <s ...

  9. 数据结构7: 循环链表(约瑟夫环)的建立及C语言实现

    链表的使用,还可以把链表的两头连接,形成了一个环状链表,称为循环链表. 和它名字的表意一样,只需要将表中最后一个结点的指针指向头结点,就形成了一个环. 图1 循环链表 循环链表和动态链表相比,唯一的不 ...

随机推荐

  1. 排名前 8 的 PHP 调试工具

    Web 开发并不是一项轻松的任务,有超级多服务端脚本语言提供给开发者,但是当前 PHP 因为具有额外的一些强大的功能而越来越流行.PHP 是最强大的服务端脚本语言之一,同时也是 web 开发者和设计者 ...

  2. Linux随笔之——./configure、make、make install(转)

    原文连接:http://www.linuxidc.com/Linux/2011-02/32211.htm 这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./con ...

  3. github生成静态博客

    github生成静态博客很简单. 1.确认你知道你github的用户名,我的叫做chenxing12 2.创建一个项目名字叫做:用户名.github.io 我的用户名叫做chenxing12,所以我创 ...

  4. CQRS, Task Based UIs, Event Sourcing agh!

    原文地址:CQRS, Task Based UIs, Event Sourcing agh! Many people have been getting confused over what CQRS ...

  5. 在SQL Server里我们为什么需要意向锁(Intent Locks)?

    在1年前,我写了篇在SQL Server里为什么我们需要更新锁.今天我想继续这个讨论,谈下SQL Server里的意向锁,还有为什么需要它们. SQL Server里的锁层级 当我讨论SQL Serv ...

  6. Final Cut Pro X效果插件开发总结

    一.介绍 最近公司需要针对Final Cut Pro(FCP)开发一款效果插件,用于对公司自己开发的视频格式进行后期处理.Final Cut Pro是苹果公司推出的一款视频剪辑软件,因此需要在OSX平 ...

  7. rsa互通密钥对生成及互通加解密(c#,java,php)

    摘要 在数据安全上rsa起着非常大的作用,特别是数据网络通讯的安全上.当异构系统在数据网络通讯上对安全性有所要求时,rsa将作为其中的一种选择,此时rsa的互通性就显得尤为重要了. 本文参考网络资料, ...

  8. c#动态加载卸载DLL的方法

    这篇文章介绍了c#动态加载卸载DLL的方法,有需要的朋友可以参考一下 c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法.在 ...

  9. C#写爬虫,版本V2.1

    这次是对2.0的小修补,2.0交互几乎没有,这次添加了进度条,和文本框,同时由于取得的链接主要会出现错误是:webResponse错误. 针对这种情况,设置了 try { webResponse = ...

  10. MyEclipse或者Eclipse内存溢出问题

    对于一些项目,我们经常会遇到内存溢出的问题,这个时候我们就需要进行设置JDK的各个内存的大小了. 如果是运行项目以后出现问题的话,那么主要还是jdk或者是tomcat的内存问题,至于网上说的xxx.i ...