针对约瑟夫问题进行的提升。在看小甲鱼的数据结构的时候看到的提问,记录后实现了出来,用集合代替循环链表来实现。
如果使用循环链表来实现的话,首先建立一个结构体,然后通过结构体指针建立循环链表,然后通过while循环,在链表中还有数据的情况下,通过for循环找到需要出列的数据,然后输出该数据,记录该节点的M值,再删除该节点,在下一个循环中执行前面的查找、记录、删除操作,直至最后一个数据结束。
问题:
编号为1~N的N个人按顺时针方向围坐一圈,每个人持有一个密码(正整数,可以自有输入)开始人选一个正整数作为报数上限值M。
从第一个人按顺序顺时针方向自1开始顺序报数,报道M时停止报数。报道M的人出列,将他的密码作为新的M值,
从他的顺时针方向上的下一个人开始从1报数,从此下去,知道最后所有人全部出列为止。
using System;using System.Collections.Generic;
using System.Linq;
namespace YueSeFuTest2
{
class Person
{
private string name; //每个人的序号(名字)
private int num; //每个人手里的密码
public int Num { get => num; set => num = value; }
public string Name { get => name; set => name = value; }
}
class Program
{
private static List<Person> person = new List<Person>();
static void Main(string[] args)
{
int num;
num = int.Parse(Console.ReadLine().Trim());
InitList(person, num); //初始化集合
Display(person); //查询初始化之后集合的结果
YueSeFu(person);
}
private static void YueSeFu(List<Person> list)
{
int length = list.Count, killPos = list[0].Num, count = list[0].Num - 1; //获取集合的长度和第一个出列的人的位置
Console.WriteLine();
while (length > 1)
{
Console.WriteLine("Name:" + list[count % length].Name + "\tPassword:" + list[count % length].Num);
killPos = list[count % length].Num; //记录新的M值
list.Remove(list[count]); //把本次出列的人从集合中剔除
length = list.Count; //跟新集合长度
count = (count + killPos - 1) % length; //更新下一个出列的人位置
}
Console.WriteLine("Name:" + list[0].Name + "\tPassword:" + list[0].Num);
}
/// <summary>
/// 初始化函数,根据队伍的人数设置他的密码和序号
/// </summary>
/// <param name="list">传入的集合</param>
/// <param name="name">传入集合的人数</param>
private static void InitList(List<Person> list,int num)
{
Person p;
Random random = new Random();
for(int i = 1; i <= num; i++)
{
p = new Person();
p.Num = random.Next(1, 5); //随机给成员的密码赋值,最小值为1,最大值不包括5
p.Name = i.ToString();
list.Add(p);
}
}
/// <summary>
/// 显示集合的所有成员名和它们的数据
/// </summary>
/// <param name="list">显示的集合</param>
private static void Display(List<Person> list)
{
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine("Name:"+list[i].Name + "\tPassword:" + list[i].Num + "\t-->");
}
}
}
}