您的位置:首页 > 理论基础 > 数据结构算法

数据结构-约瑟夫问题(环形链表)

2020-08-22 21:17 1206 查看

约瑟夫问题

问题描述

约瑟夫问题:有N个小孩围成一圈,给他们从1开始依次编号,现指定从第K个开始报数,报到第m个时,该小孩出列,然后从下一个小孩开始报数,仍是报到m个出列,如此重复下去,直到所有的小孩都出列(总人数不足m个时将循环报数),求小孩出列的顺序。

环形链表的建立和遍历图解

约瑟夫问题的解决步骤图解

代码

代码的注意事项

在写计算去除顺序时,我用的辅助指针为temp 和 cur
temp指向报到m的那个小孩
cur指向报到m的那个小孩的前一个
其实也可以修改代码只用一个辅助指针,因为本来就有一个辅助指针first,
这样最后可以不用把first指向cur就可以回收节点,很是舒服

package 约瑟夫问题_环形链表;

public class Josephu {
public static void main(String[] args) {
CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();

circleSingleLinkedList.addBoy(5);

circleSingleLinkedList.countBoy(3,3,5);

circleSingleLinkedList.list();
}

}

class CircleSingleLinkedList{
private BoyNote first = new BoyNote(-1);

//建立环形链表
public void addBoy(int nums){
if (nums < 1){
System.out.println("nums值不正确");
return;
}
BoyNote cur = null;
first.setNo(1);
cur = first;
cur.setNext(first);
for (int i = 2; i <= nums; i++) {
BoyNote boyNote = new BoyNote(i);
cur.setNext(boyNote);
boyNote.setNext(first);
cur = cur.getNext();
}
}

//遍历环形链表
public void list(){
if (first.getNext() == null){//注意此处不能判断first为不为空,first一直都是有的
System.out.println("没有任何小孩");
return;
}
BoyNote temp = first;
int sums = 0;
while (temp.getNext() != first){
System.out.println(temp);
temp = temp.getNext();
sums++;
}
System.out.println(temp);
System.out.println("一共有"+(sums+1)+"个小孩");
}

/**
*
* @param startNo 从第几个小孩开始数数
* @param countNum  表示数几下
* @param nums  多少个小孩在圈中
*/
//计算出小孩出圈的顺序
public void countBoy(int startNo, int countNum, int nums){
if (first.getNext() == null || startNo < 1 || startNo > nums){
System.out.println("参数输入有误");
return;
}
BoyNote cur = first;
for (int i = 1; i < startNo; i++) {
cur = cur.getNext();
}
BoyNote temp;
while (cur.getNext() != cur){
for (int i = 0; i < countNum - 2; i++) {
cur = cur.getNext();
}
temp = cur.getNext();
System.out.print(temp+"---->");
cur.setNext(temp.getNext());
cur = cur.getNext();
}
first = cur;//把开始first指向的那个节点回收
System.out.println("最够留在圈内的小孩的"+first);
}
}

class BoyNote{
private int no;
private BoyNote next;

public BoyNote(int no) {
this.no = no;
}

public int getNo() {
return no;
}

public void setNo(int no) {
this.no = no;
}

public BoyNote getNext() {
return next;
}

public void setNext(BoyNote next) {
this.next = next;
}

@Override
public String toString() {
return "编号为 "+no;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: