约瑟夫环(单向循环链表)
链表节点
public class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
}
}
构造单向循环链表
/**
* 单向循环链表
*/
public class SingleLoopLink {
private Node head; // 引用头节点
private Node last; // 引用最后一个节点
// 末尾插入一个元素,单元素插入
private boolean add(int e) {
Node node = new Node(e);
if (head == null) {
head = node;
head.next = head;
last = head;
return true;
}
node.next = last.next;
last.next = node;
last = node; // last指向最后一个节点
return true;
}
// 返回头节点
public Node getHead() {
return head;
}
// 打印单向循环链表
public String print() {
if (head == null) return "[]";
Node p = head;
StringBuilder sb = new StringBuilder();
while (p.next != head) {
sb.append(p.data + ", ");
p = p.next;
}
sb.append(p.data);
return "[" + sb.toString() + "]";
}
/**
* 单向循环链表解决约瑟夫环问题
* 假设有11(1-11)个小孩,数到7的小孩离开,那么胜利者是哪个小孩呢?出圈的顺序又是多少?
* 共有 n=11人, 喊到m=7 出列。
* 出圈的顺序为:7 3 11 9 8 10 2 6 1 4 5
*/
public void round(int n, int m) {
if (n < m) {
System.out.println("n不能小于m");
return;
}
for (int i = 0; i < n; i++) {
add(i + 1);
}
System.out.println("链表中的元素:" + print());
// 计数器 到7出列,从1开始
int count = 1;
while (head.next.data != head.data) {
// 如果count=7,删除当前节点,重置count=1
if (count == m) {
System.out.println("离开:" + head.data);
head.data = head.next.data;
head.next = head.next.next;
count = 1;
continue;
}
count++;
head = head.next;
}
System.out.println("胜利者:" + head.data);
}
}
测试
public class AppTest {
public static void main(String[] args) {
SingleLoopLink link = new SingleLoopLink();
link.round(11, 7);
}
}
结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律