:链表 -- 单向环形链表约瑟夫问题(约瑟夫环)
Posted CodeJiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了:链表 -- 单向环形链表约瑟夫问题(约瑟夫环)相关的知识,希望对你有一定的参考价值。
1. 约瑟夫问题(约瑟夫环)
约瑟夫问题(约瑟夫环):
设编号为1,2…,n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,
数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人出列,
它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,
由此产生一个出队编号的序列。
2. 单向环形链表介绍
采用一个单项环形链表来处理(可以带表头也可以不带表头),具体使用头结点还是不带头结点,后面会具体分析。
约瑟问题示意图:
- n=5,即有5个人
- k=1,从第一个人开始报数
- m=2,数2下
3. 解决约瑟夫问题分为两个步骤
- 第一步:做环形链表
- 第二步:解决约瑟夫问题
BoyNode.java
package data_structure;
/**
* 结点类
*/
public class BoyNode
//结点编号
private int no;
//指向下一个节点
private BoyNode next;
public BoyNode(int no)
this.no = no;
public int getNo()
return no;
public void setNo(int no)
this.no = no;
public BoyNode getNext()
return next;
public void setNext(BoyNode next)
this.next = next;
CircleSingleLinkedList.java
package data_structure;
public class CircleSingleLinkedList
private BoyNode first = new BoyNode(-1);
/**
* 构建环形链表 5
*/
public void addBoy(int nums)
if (nums < 1)
System.out.println("数据不正确");
return;
BoyNode temp = null;
for (int i = 1; i <= nums; i++)
BoyNode boyNode = new BoyNode(i);
/*
* 判断你是否是第一个小孩
*/
if (i == 1)
first = boyNode;
first.setNext(first);
temp = first;
else
temp.setNext(boyNode);
boyNode.setNext(first);
temp = boyNode;
/**
* 查看环形链表中的节点
*/
public void showBoy()
if (first == null)
System.out.println("链表为空..");
return;
BoyNode boyNode = first;
while (true)
System.out.printf("小孩子的编号%d\\n", boyNode.getNo());
if (boyNode.getNext() == first)
break;
boyNode = boyNode.getNext();
/**
* 当调用该方法输入第几个小孩子开始数数,数几次,环形链表中一共几个小孩
*/
public void countBoy(int startNo, int countNum, int nums)
if (first == null || startNo < 1 || startNo > nums)
System.out.println("参数输入有错误...");
return;
/*
* 定义辅助指针,指向的是环形单链表中的最后一个节点
*/
BoyNode helper = first;
while (helper.getNext() != first)
helper = helper.getNext();
/*
* 寻找起始位置,把first定义为起始位置
*/
for (int j = 0; j < startNo - 1; j++)
first = first.getNext();
helper = helper.getNext();
/*
* 当小孩进行报数时,数到m的孩子进行出列,让first和helper移动m-1次即可,找到了
* 出列孩子
*/
while (helper != first)
for (int j = 0; j < countNum - 1; j++)
first = first.getNext();
helper = helper.getNext();
System.out.printf("小孩子%d 出列\\n", first.getNo());
first = first.getNext();
helper.setNext(first);
System.out.printf("最后出圈的小孩编号%d\\n", first.getNo());
LinkedTest.java
package data_structure;
public class LinkedTest
public static void main(String[] args)
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
circleSingleLinkedList.addBoy(5);
circleSingleLinkedList.showBoy();
circleSingleLinkedList.countBoy(1, 2, 5);
运行结果:
以上是关于:链表 -- 单向环形链表约瑟夫问题(约瑟夫环)的主要内容,如果未能解决你的问题,请参考以下文章