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. Android设置按钮透明

    <Button android:id="@+id/bt3" android:layout_width="163dp" android:layout_hei ...

  2. java——定时任务

    java定时任务直接看代码 public void timeTask(){ Timer timer = new Timer(); timer.schedule(new TimerTask() { pu ...

  3. mybatis是怎样炼成的

    前言 一些个人感受:不管分析什么源码,如果我们能摸索出作者的心路历程,跟着他的脚步一步一步往前走,这样才能接近事实的真相,也能更平滑更有趣的学习到知识.跟福尔摩斯探案一样,作者都经历了些什么,为什么他 ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射

    上一篇文章(https://www.cnblogs.com/meowv/p/12961014.html)集成了定时任务处理框架Hangfire,完成了一个简单的定时任务处理解决方案. 本篇紧接着来玩一 ...

  5. Java IO(十七)FIleReader 和 FileWriter

    Java IO(十七)FIleReader 和 FileWriter 一.介绍 FIleReader 和 FileWriter 是读写字符文件的便利类,分别继承于 InputStreamReader ...

  6. Java找零钱算法

    买东西过程中,卖家经常需要找零钱.现用代码实现找零钱的方法,要求优先使用面额大的纸币,假设卖家有足够数量的各种面额的纸币. 下面给出的算法比较简单,也符合人的直觉:把找零不断地减掉小于它的最大面额的纸 ...

  7. IT笑话十则(一)

    一.下班前发给你 客户:“这个图下班之前必须发给我!” 设计师:“好的!” 第二天清早. 客户:“图怎么还没发过来?” 设计师:“我还没下班呢…”   二.受伤的老三 行业老大与老二PK,受伤的并非对 ...

  8. Rocket - tilelink - Bits vs. UInt

    https://mp.weixin.qq.com/s/lzDmIHkUph3b1Fxgx66ySg   分析移位/取反操作在Intellij中提示错误的问题.   1. 问题   用到移位/取反的地方 ...

  9. 【Linux】CentOS7中使用mysql,查询结果显示中文乱码的解决办法

    1.登录mysql mysql -u root -p 2.查看mysql字符集 mysql> show variables like 'chara%'; mysql> show varia ...

  10. Java实现 LeetCode 241 为运算表达式设计优先级

    241. 为运算表达式设计优先级 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 +, - 以及 * . 示例 ...