c#单向链表实现约瑟夫环
构建一个单项的环形链表思路
- 先创建第一个节点,让first指向该节点,并形成环形
- 后面当我们每创建一个新的节点,就把该节点加入到已有的环形链表中即可。
遍历环形链表
- 先让一个辅助指针(变量)currentNode,指向first节点
- 然后通过一个while循环遍历该循环链表即可currentNode.next == first结束
public class PersonNode
{
public int Id { get; set; }
public PersonNode(int id)
{
Id = id;
}
public PersonNode NextPerson { get; set; }
}
/// <summary>
/// 创建一个环形的单向链表
/// </summary>
public class MyJoseph
{
//创建一个头节点,不包含任何意义的数据
private PersonNode first = new PersonNode(-1);
/// <summary>
/// 添加节点
/// </summary>
/// <param name="num">需要创建几个节点</param>
public void addPerson(int num)
{
if (num <= 0)
{
Console.WriteLine("num的值不正确");
return;
}
//辅助指针帮助构建环形链表
PersonNode currentNode = null;
//使用for循环创建我们的环形链表
for (int i = 1; i <= num; i++)
{
//根据编号创建节点
PersonNode person = new PersonNode(i);
//如果是第一个节点
if (i==1)
{
first = person;
first.NextPerson = first; //构成环形
currentNode = first;//让currentNode指向第一个节点,因为fist节点不能动
}
else
{
//让当前节点指向新增加的节点
currentNode.NextPerson = person;
//将新增的节点指向第一个节点完成闭环
person.NextPerson = first;
//改变当前节点的位置
currentNode = person;
}
}
}
public void Print()
{
if (first == null)
{
Console.WriteLine("链表为空");
return;
}
PersonNode currentNode = first;
while (true)
{
Console.WriteLine($"编号{ currentNode.Id }");
if (currentNode.NextPerson == first) break;
currentNode = currentNode.NextPerson;
}
}
/// <summary>
/// 踢出圈
/// </summary>
/// <param name="startId">从第几个人开始踢</param>
/// <param name="num">数几次</param>
/// <param name="personNum">圈内总人数</param>
public void