1. 约瑟夫问题
加斯帕·蒙日是法国数学家,他在《数学的游戏问题》中讲了一个故事:15个教徒和15个非教徒在深海上遇险,必须将一半的人投入海中,其余人才能幸免于难,于是想了一个方法,30个人 围城一圈,从第一个人开始依次报数,每数到第九个的人就将他扔向大海,如此循环进行直到仅剩余15个人为止。问怎样的排法,才能使每次投入大海的都是非教徒?这就是著名的约瑟夫问题,又称约瑟夫环。
我们将问题进行一下抽象:N个人进行手尾排列,从第一个开始数数,数到第X个停止,然后把第X个剔除;然后接着数,数到第X个停止,并将其移除,以此类推,直到达到要剔除的个数数目,把这些剔除位置的记录下来,就是我们所需要的位置。很显然,循环链表非常适合解决这个问题。
2. 解决思路
(1). 先抽象出一个单向的循环链表,要有尾节点,尾节点指向头节点;可以用当前节点的前驱节点来表示当前节点。
代码如下:
节点
1 /// <summary> 2 /// 循环链表节点 3 /// </summary> 4 public class CircleNode<T> 5 { 6 /// <summary> 7 /// 存放数据 8 /// </summary> 9 public T Data { get; set; } 10 11 /// <summary> 12 /// 下一个节点 13 /// </summary> 14 public CircleNode<T> Next { get; set; } 15 16 public CircleNode() 17 { 18 19 } 20 21 public CircleNode(T data) 22 { 23 Data = data; 24 } 25 }