文章目录
链表的最后一个节点指向第一个节点,形成一个环状的链表;
模拟实现约瑟夫问题
package com.xiaozhi.day03linkedlist.josephquestion;
/**
* @author by @CSDN 小智RE0
* @date 2021-12-23
*/
public class JosephQuestion {
//节点类;
static class ListNode {
int val;
ListNode next;
ListNode(int x, ListNode next) {
this.val = x;
this.next = next;
}
}
public static void main(String[] args) {
//定义一个环形链表;模拟约瑟夫问题;
//开始的节点;
ListNode start = null;
//当前节点的上一个节点;
ListNode preNode = null;
//为节点初始化赋值;
for (int i = 1; i <= 41; i++) {
//首节点;
if (i == 1) {
start = new ListNode(i, null);
preNode = start;
continue;
}
ListNode node = new ListNode(i, null);
preNode.next = node;
//让添加的节点作为前缀节点;
preNode = node;
//最后一个节点
if (i == 41) {
preNode.next = start;
}
}
//定义计数器;
int count = 0;
//实际操作节点;
ListNode opNode = start;
//当前节点的上一个节点;
preNode = null;
//直到节点剩余一个为止
while (opNode != opNode.next) {
//模拟约瑟夫问题中的报数;
count += 1;
//判断报数位置是否为3;
if (count == 3) {
//这一步操作,意味着要把目前这个操作节点扔出去;
preNode.next = opNode.next;
System.out.println("出去->" + opNode.val);
//重置计数器;
count = 0;
} else {
//否则,很幸运,当前节点就暂时作为前缀节点吧;
preNode = opNode;
}
//操作节点后移;
opNode = opNode.next;
}
//输入剩余的节点;
System.out.println("最终节点->" + opNode.val);
}
}
测试结果,最后留下的两个节点为16号和31号
出去->3
出去->6
出去->9
出去->12
出去->15
出去->18
出去->21
出去->24
出去->27
出去->30
出去->33
出去->36
出去->39
出去->1
出去->5
出去->10
出去->14
出去->19
出去->23
出去->28
出去->32
出去->37
出去->41
出去->7
出去->13
出去->20
出去->26
出去->34
出去->40
出去->8
出去->17
出去->29
出去->38
出去->11
出去->25
出去->2
出去->22
出去->4
出去->35
出去->16
最终节点->31