重新整理数据结构与算法——环形链表[五]

前言

有一个需求:

上面这张图,要求数到数数,比如说数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();
}

结果

下一节

整理的排序算法不晓得到哪里去了,后面是查询算法,之后再回到排序算法。

原文地址:https://www.cnblogs.com/aoximin/p/13083938.html