1.介绍

Josephu问题为:设编号为1、2、...n的n个人围坐在一圈,约定编号为k(1<=k<=n) 的人从1开始报数,

数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,以此类推,直到所有人都出列为止,由此产生出一个出列编号的序列。

2.提示

用一个不带头节点的循环链表来处理Josephu问题:先构成一个有n节点的单向循环链表,

然后由k节点起从1开始计数,计到m时,对应节点从链表中删除,然后再重被删除节点的下一个节点又从1开始计数,直到最后一个节点从链表中删除算法结束

3.示意图

4.环形链表示意图

5.思路分析图

6.代码实现

    public class Boy
{
public Boy(int id)
{
this.Id = id;
}
public int Id { get; set; } public Boy Next { get; set; }
}
    public class CircleSingleLinkList
{
private Boy _first = null; public void Add(int nums)
{
if (nums < ) Console.WriteLine("传入的值必须大于1");
else
{
Boy curBoy = null; for (int i = ; i <= nums; i++)
{
Boy boy = new Boy(i); if (i == )
{
_first = boy;
_first.Next = _first; //构成环形
curBoy = _first; //让当前boy等于第一个小孩
} else
{
curBoy.Next = boy; //指向当前小孩的下一个
boy.Next = _first; //待添加的小孩的下一个节点指向第一个
curBoy = boy;//再把当前小孩指向待添加节点
}
}
}
} /// <summary>
/// 根据用户的输入,计算出小孩出圈的顺序
/// </summary>
/// <param name="startId">表示从第几个小孩开始数数</param>
/// <param name="countNum">表示数几下</param>
/// <param name="nums">表示最初由几个小孩在圈中</param>
public void CountBoy(int startId,int countNum,int nums)
{
if (startId < || startId > nums || _first == null)
{
Console.WriteLine("参数错误请重新输入"); return;
} Boy helper = _first; //创建一个辅助节点 //将辅助节点指向最后一个节点
while (true)
{
if (helper.Next == _first) break; //当辅助节点的下一个节点等于第一个节点 说明是最后一个节点 helper = helper.Next;
} //将开始节点和辅助节点指向开始数数的位置和结尾 由于索引是从0开始所以是startId-1
for (int j = ; j < startId- ; j++)
{
_first = _first.Next;
helper = helper.Next;
} //当小孩报数时,让first和helper同时移动 countNum-1次,然后出圈
while (true)
{
if (helper == _first) break; //当尾结点等于头节点时 说明只有一个节点 for (int i = ; i < countNum-; i++)
{
_first = _first.Next;
helper = helper.Next;
} //first就代表出圈的小孩
Console.WriteLine($"出圈的小孩:{_first.Id}"); _first = _first.Next; //将first指向小孩节点出圈
helper.Next = _first;
}
Console.WriteLine("最后留下的小孩:"+_first.Id);
}
    public class Josephu
{
public static void Test()
{
CircleSingleLinkList singleLinkList = new CircleSingleLinkList(); singleLinkList.Add(); singleLinkList.ShowBoy(); singleLinkList.CountBoy(, , );
}
}

7.效果演示图

C#数据结构与算法系列(七):约瑟夫问题(Josephu)的更多相关文章

  1. javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例

    栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...

  2. Java数据结构和算法(七)B+ 树

    Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...

  3. 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解

    数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...

  4. 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解

    数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...

  5. 数据结构与算法系列研究七——图、prim算法、dijkstra算法

    图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...

  6. 数据结构与算法系列——排序(4)_Shell希尔排序

    1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...

  7. 看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文

    <看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的样子. 关于LSM树 ...

  8. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  9. 数据结构与算法系列----AC自己主动机

    一:概念 首先简要介绍一下AC自己主动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之中的一个.一个常见的样例就是给出n个单词,再给出一段 ...

  10. 数据结构与算法系列----最小生成树(Prim算法&amp;Kruskal算法)

     一:Prim算法       1.概览 普里姆算法(Prim算法).图论中的一种算法.可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中.不但包含了连通图里的全部顶点(英语:Ve ...

随机推荐

  1. LinkedList为什么增删快、查询慢

    List家族中共两个常用的对象ArrayList和LinkedList,具有以下基本特征. ArrayList:长于随机访问元素,中间插入和移除元素比较慢,在插入时,必须创建空间并将它的所有引用向前移 ...

  2. [UWP]使用离散式关键帧播放动画

    这篇文章介绍离散式关键帧,并使用它做些有趣的动画. 1. 什么是离散式关键帧 以DoubleAnimationUsingKeyFrames为例,它支持四种Double的关键帧,其中EasingDoub ...

  3. springboot系列——重试机制原理和应用,还有比这个讲的更好的吗(附完整源码)

    1. 理解重试机制 2. 总结重试机制使用场景 3. spring-retry重试组件 4. 手写一个基于注解的重试组件 5. 重试机制下会出现的问题 6. 模板方法设计模式实现异步重试机制 如果有, ...

  4. MANIFEST.MF是个什么?

    MANIFEST.MF是个什么? 写这篇文件主要记录JRA文件里面到底是什么?然后MANIFEST.MF又是什么?Springboot 如何只有Main方法就可以运行的? Springboot项目打包 ...

  5. DataFrame-选择与切片

    取得DataFrame对象reviews的description列的前10个值(或者说reviews前10行的description列): reviews.iloc[:10].loc[:,'descr ...

  6. 485通信——驱动 MX64/MX28 舵机

    背景:在使用STM32调试MX64舵机时,由于控制该舵机需要采用RS485通信协议,因此需要从单片机的串口经过一个TTL转485通信的模块再与舵机进行通信. 485通信特点: 485通信采用差分信号: ...

  7. vc程序设计--图形绘制1

        利用绘图函数创建填充区.Windows通过使用当前画笔画一个图形的边界,然后用当前的刷子填充这个图形来创建-一个填充图形.共有三个填充图形,第一个是用深灰色画刷填充带圆角的矩形,第二个是采用亮 ...

  8. jchdl - 门和开关层(GSL)

    https://mp.weixin.qq.com/s/dcBfMLOuaFtrk6i149vIVQ   第一部分 静态建模:拓扑模型   GSL层拓扑建模相对简单,由线和节点组成: 线连接各个节点: ...

  9. 前端HTML学习 table标签 知识点与使用

    表格基本结构 <table> <tr> <td>单元格</td> </tr> </table> < tr >表示 行 ...

  10. Go 语言入门教程:安装

    关注公众号:雨哥写 python. 学习 Go 语言,比较下和 python 的用法,争取对 python 有更深的理解. 为什么学 Go 我主要使用 python 语言,其他语言用得不多,希望学一门 ...