前言
有一个需求:
上面这张图,要求数到数数,比如说数2,如果数到2,那个人就退出去,其他人继续数,问最后留在圈子里面的人是谁?
这个可以用环形链表实现。
正文
思路
1.首先要形成一个环形链表。
2.第二个就是要想到如何删除一个节点。
3.如何最优判断删除剩下最后一个节点。
其实看过在三中介绍了,链表要删除一个节点,最好的方法就是知道它的前一个结点,然后只要把他的前一个节点的next,重置给当前要删除的next即可,这样就从链表中删除了。
所以需要两个引导项,一个是当前小孩,一个是当前小孩的前一个。
那么什么时候判断为最后一个节点呢?
就是这两个引导项相同的时候。
代码
public class Josepfu
{
public Children first;
public int numbers;
public void showBoy()
{
if (first == null)
{
Console.WriteLine("无任何小孩!");
}
Children curBoy = first;
while (true)
{
Console.Write(curBoy.number+" ");
if (curBoy.next == first)
{
break;
}
curBoy = curBoy.next;
}
Console.WriteLine();
}
/// <summary>
/// 初始化小孩个数
/// </summary>
/// <param name="numbers"></param>
public void addChilds(int numbers) {
this.numbers = numbers;
// 校验数据不对
if (numbers < 1)
{
throw new Exception("你输入的数据不能小于1!");
}
Children curBoy = null;
for (int i = 1; i <= numbers; i++)
{
var child = new Children(i);
if (i == 1){
//初始化第一个节点
first = child;
first.next = first;
curBoy = first;
}
else {
curBoy.next = child;
child.next = first;
curBoy = child;
}
}
}
/// <summary>
/// 数数弹出小孩函数
/// </summary>
/// <param name="startNo">从哪个小孩开始数</param>
/// <param name="count">报数是多少</param>
public void outChild(int startNo,int count) {
if (numbers == 0)
{
throw new Exception("你还没有初始化小孩!");
}
if (startNo < 1&&startNo>numbers)
{
throw new Exception("报数小孩不存在");
}
//特殊情况判断
if (first.next == first)
{
Console.WriteLine(first.number);
return;
}
// 初始化一个引导小孩
Children helper = first;
while (true)
{
if (helper.next == first)
{
break;
}
helper = helper.next;
}
// 定位到第一个报数小孩
for (int i = 0; i < startNo-1; i++)
{
first = first.next;
helper = helper.next;
}
//开始报数
while (true)
{
if (first == helper)
{
break;
}
//自己要数一下
for (int i = 0; i < count-1; i++)
{
first = first.next;
helper = helper.next;
}
first = first.next;
helper.next = first;
}
Console.WriteLine(first.number);
}
}
public class Children {
public int number;
public Children next;
public Children(int number,Children next)
{
this.number = number;
this.next = next;
}
public Children(int number):this(number,null)
{
}
}
测试
static void Main(string[] args)
{
Josepfu josepfu = new Josepfu();
josepfu.addChilds(7);
josepfu.showBoy();
josepfu.outChild(1,2);
Console.ReadKey();
}
结果
下一节
整理的排序算法不晓得到哪里去了,后面是查询算法,之后再回到排序算法。