实现约瑟夫环形链表
Posted loremwalker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现约瑟夫环形链表相关的知识,希望对你有一定的参考价值。
题目
41个人排成一个圆圈,由第1个人 开始报数,每报数到第3人,该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。约瑟夫与朋友在第16与第31个位置,于是活了下来。请用单向环形链表描述该结构并呈现整个自杀过程。
设计
- 首先要设计一个节点模型
class Node {
int value;
Node next;
Node(int value) {
this.value = value;
}
}
- 遍历并用 last 节点做成一个单向线性的链表,之后将自身的初始节点指向last.next 节点,扣成一个环
Node head = new Node(1);
Node last = head;
/** 一条单链数据 */
for (int i = 2; i <= n; i++) {
last = (last.next = new Node(i));
}
/**
回调指向,形成环形链,可用如下代码做环形链表是否形成的测试
System.out.println(last.next.next.value);
*/
last.next = head;
- 遍历每个报数到m(m=3)的节点,并重组链表
for (int i = 1; i < m; i++) {
last = last.next; //6
}
/**首先以总人数3为例,再以6为例推测这段代码,以及结合for循环就很好理解了*/
last.next = last.next.next; //3、4、5
- 整个自杀链表遍历的结束条件
/**
以总人数 3 为例 last.next 经过遍历为3时赋值给 last ,
此时 last==last.next 是成立的,即可跳出while循环
*/
while (last != last.next) {
for (int i = 1; i < m; i++) {
last = last.next;
}
last.next = last.next.next;
}
实现
import org.junit.Test;
import static java.lang.System.out;
/**
* @author lorem
*/
public class NodeNodeNext {
class Node {
int value;
Node next;
Node(int value) {
this.value = value;
}
}
@Test
public void test() {
winner(41, 3);
}
void winner(int n, int m) {
Node head = new Node(1);
Node last = head;
/** 一条单链数据 */
for (int i = 2; i <= n; i++) {
last = (last.next = new Node(i));
}
/**回调指向,形成环形链*/
last.next = head;
out.println("依次死亡的序号:");
while (last.value != last.next.value) {
for (int i = 1; i < m; i++) {
last = last.next;
}
out.print(last.next.value + " ");
last.next = last.next.next;
}
out.println("
" + "最后存活的序号:");
out.printf("%d", last.value);
}
}
以上是关于实现约瑟夫环形链表的主要内容,如果未能解决你的问题,请参考以下文章