Java使用单链表实现约瑟夫环攻略
1. 约瑟夫环问题简介
约瑟夫环问题是一个经典的数学问题,题目如下:
$n$个人围成一圈,依次从第 $k$ 个人开始报数,报到 $m$ 的人出列,下一个人重新从 $1$ 开始报数,直到所有人出列。求最后出列的人。
2. 解法思路
最常见的解法是使用单链表模拟这个过程,通过不停地删除节点来模拟人员出列的过程。具体思路如下:
- 首先构建一个带头结点的单链表,并对链表中的每一个节点进行编号。
- 从第 $k$ 个节点开始,开始模拟报数的过程。每次报数时,直接走 $m-1$ 步,然后将当前节点从链表中删除。
- 当删除节点的数量达到 $n$ 时,约瑟夫环结束,最后一个节点即为答案。
3. 代码实现
下面是Java实现约瑟夫环的代码,其中使用了自己实现的单链表 LinkedList
:
public class Josephus {
public static void main(String[] args) {
int n = 5; // n个人围成的环
int k = 2; // 从第k个人开始报数
int m = 3; // 报到m的人出列
LinkedList<Integer> list = new LinkedList<>();
for (int i = 1; i <= n; i++) {
list.add(i);
}
int index = k;
while (list.size() > 1) {
int removeIndex = (index + m - 2) % list.size(); // 计算需要删除的元素的下标
list.remove(removeIndex);
index = removeIndex + 1; // 下一次从删除元素的后一个元素开始数
}
System.out.println("最后一个人的编号是:" + list.get(0));
}
}
上面的代码中,我们首先构建了一个链表,并将链表中的每一个节点按照编号进行初始化。接着,我们循环模拟报数的过程,通过删除链表中的节点来模拟人员出列的过程。最后,当删除的节点个数达到 $n$ 时,约瑟夫环结束,最后一个节点即为答案。
4. 示例说明
下面举两个约瑟夫环的实际示例,来更好地理解这种数据结构的使用。
示例一
假设有 $n=7$ 个人围成一圈,从第 $k=3$ 个人开始报数,每报到 $m=4$ 的人出列。
初始状态下,链表中各个节点的编号为:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7
第一次报数后,删除编号为 $6$ 的节点,剩下的链表中各个节点的编号为:
1 -> 2 -> 3 -> 4 -> 5 -> 7
第二次报数后,删除编号为 $2$ 的节点,剩下的链表中各个节点的编号为:
1 -> 3 -> 4 -> 5 -> 7
第三次报数后,删除编号为 $5$ 的节点,剩下的链表中各个节点的编号为:
1 -> 3 -> 4 -> 7
第四次报数后,删除编号为 $1$ 的节点,剩下的链表中各个节点的编号为:
3 -> 4 -> 7
第五次报数后,删除编号为 $7$ 的节点,剩下的链表中各个节点的编号为:
3 -> 4
第六次报数后,删除编号为 $4$ 的节点,此时链表中只剩下一个节点,即最后的答案。
示例二
假设有 $n=10$ 个人围成一圈,从第 $k=1$ 个人开始报数,每报到 $m=3$ 的人出列。
初始状态下,链表中各个节点的编号为:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
第一次报数后,删除编号为 $3$ 的节点,剩下的链表中各个节点的编号为:
1 -> 2 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
第二次报数后,删除编号为 $6$ 的节点,剩下的链表中各个节点的编号为:
1 -> 2 -> 4 -> 5 -> 7 -> 8 -> 9 -> 10
第三次报数后,删除编号为 $10$ 的节点,剩下的链表中各个节点的编号为:
1 -> 2 -> 4 -> 5 -> 7 -> 8 -> 9
第四次报数后,删除编号为 $5$ 的节点,剩下的链表中各个节点的编号为:
1 -> 2 -> 4 -> 7 -> 8 -> 9
第五次报数后,删除编号为 $2$ 的节点,剩下的链表中各个节点的编号为:
1 -> 4 -> 7 -> 8 -> 9
第六次报数后,删除编号为 $8$ 的节点,剩下的链表中各个节点的编号为:
1 -> 4 -> 7 -> 9
第七次报数后,删除编号为 $4$ 的节点,剩下的链表中各个节点的编号为:
1 -> 7 -> 9
第八次报数后,删除编号为 $1$ 的节点,剩下的链表中各个节点的编号为:
7 -> 9
第九次报数后,删除编号为 $9$ 的节点,此时链表中只剩下一个节点,即最后的答案。
5. 总结
本文介绍了使用单链表实现约瑟夫环的方法,同时提供了两个实例来对这个思路进行进一步的理解。约瑟夫环问题在求解过程中关键是考虑到每一次报数后应该删除的节点,这里我们通过使用单链表中删除节点的方式来模拟这一过程,最终得到约瑟夫环问题的解答。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java使用单链表实现约瑟夫环 - Python技术站