单向循环链表节点
public class Node{public int id;public Node next;public Node(int id){this.id = id;}}
单向循环链表对象类
public class SingleLoopLinkList{//先默认创建第一个节点,这个节点不是头结点,是有效节点,默认数据是要修改的Node first = new Node(-1);public SingleLoopLinkList(){//初始化的时候默认把第一个节点环起来,环形链表嘛,一个节点也要环起来first.next = first;}//显示节点数据public void Show(){Node temp = first;while (true){Console.WriteLine(temp.id);if(temp.next==first){break;}temp = temp.next;}}}
添加节点
在SingleLoopLinkList类里面的方法
//添加节点public void Add(Node node){if (first.id == -1){//如果第一个节点的数据是默认数据,则这次的添加就是第一次添加数据,就把数据赋值给firstfirst.id = node.id;}else//到了这一步,就说明第一个first节点已经有了真实数据{//当前指针,从first的下一个开始,因为是环形的,不用担心空指针Node cur = first.next;while (true){if (cur.next == first)//如果当前节点的下一个就是first节点,说明当前节点就是最后一个节点{node.next = first;cur.next = node;break;}cur = cur.next;}}}
Josephu(约瑟夫)问题
描述
设编号1,2,3,…..,n的n个人围坐在一圈,约定编号为k(1<=k<=n)的人开始从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,以此类推,直到所有人出列为止,由此产生一个出队编号的序列。
思路
代码
在SingleLoopLinkList类里面的方法
在调用Josephu之前,先添加节点
public void Josephu(int k, int m){Node temp = first;//辅助指针//1.先把temp指向first之前的一个节点,因为first是第一个节点,所以遍历这个链表,找到最后一个节点,就是first前一个节点了while (true){if (temp.next == first)//说明temp就是最后一个了{break;}temp = temp.next;}//2.把temp和first移动k-1次,因为要从第k个开始数,first移动k-1此后,first就是第k个for(int i = 0; i < k-1; i++){first = first.next;temp = temp.next;}//3.循环出圈(直到圈中只有一个节点):first和temp都同时移动m-1个,自身报数1,移动m-1就是报数m,然后出圈while (true){if (temp == first)//说明圈中只有一个节点{break;}//first和temp都同时移动m-1个for(int j = 0; j < m - 1; j++){first = first.next;temp = temp.next;}//这时候first指向节点就是要出圈的节点Console.WriteLine($"出圈:{first.id}");//这时候要将出圈的first删掉,既然first就是要被删除的节点,单链表删除节点是要用到被删除节点的上一个辅助节点//temp不就是被删除节点first的上一个节点吗first = first.next;temp.next = first;//这两句代码和单链表删除节点的temp.next=temp.next.next一样,temp指被删除节点的上一个节点}//当到了这里,说明链表就剩一个了,最后一个出圈Console.WriteLine($"出圈:{first.id}");}
————
————
————
————
