package csdn2;
/**使用环形链表(以单链表为基础)实现约瑟夫环(Josephus)
* @author Babulakaka
* @create 2021-06-12 8:30
*/
public class CircleLinkedList {
public static void main(String[] args) {
Josephus josephus = new Josephus();
josephus.Circle(5);//2 4 1 5 3
josephus.show();
josephus.gameBegin(1,2,5);
}
}
class Node{
int val;//每个节点的编号
Node next;//下一个节点
public Node(){
}
public Node(int val){
this.val = val;
}
}
class Josephus{
Node first = new Node();//用于指向编号为1的节点
//生成一个节点数量为n的环(基础为单链表的添加)
public void Circle(int n){
Node cur = first;//用来遍历
for(int i = 1;i<=n;i++) {
Node node = new Node(i);//每个节点序号从1开始一次递增.
if (i == 1) {
first=node;
cur=first;
first.next=first;//形成环
}else {
cur.next=node;
node.next=first;//使得新来的节点与旧的节点成环
cur=cur.next;//使得cur节点始终指向最新添加的节点
}
}
}
//start表示从编号为start的节点开始叫号(从1开始),count表示叫到为count的节点出圈,num是圈节点的总个数
public void gameBegin(int start,int count,int num){
Node helper = first;//用于配合first,完成出圈操作
while (true){
if(helper.next==first){
break;
}
helper=helper.next;
}
//首先限制一下start不允许超过圈的总人数
if (start > num || start <= 0) {
System.out.println("输入数据错误,无法进行游戏");
}
//让first指针指向开始的节点
while (true){
if(first.val==start){
break;
}
first=first.next;
helper=helper.next;
}
while(true) {
//根据count来判断first和helper要移动几步(移动count-1步)
for (int i = 0; i < count - 1; i++) {
first = first.next;
helper = helper.next;
}
System.out.println("出圈的节点为:"+first.val);
//现在只需要将first往后面在移动一个节点,配合helper就可以将数到count的节点出圈
first = first.next;
helper.next = first;
if(first==helper){//还剩下最后一个圈内的节点,退出循环
break;
}
}
//完成循环,将最后一个节点输出
System.out.println("最后圈内还剩下节点:"+first.val);
}
//用来展示当前环形链表
public void show(){
Node temp=first;
if(first==null){
System.out.println("当前圈还没有节点");
return;
}
System.out.println("当前链表成员");
while (true){
System.out.println(temp.val);
if(temp.next==first){
break;
}
temp=temp.next;
}
}
}
使用环形链表实现约瑟夫环
最新推荐文章于 2022-07-21 20:44:07 发布