约瑟夫问题
Node类
package com.josephu.test;
public class Node {
private int id;
private Node next; //指向下一个结点
public Node(int id){
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node [id=" + id + "]";
}
}
JosephuSample类
package com.josephu.test;
/**
* 约瑟夫问题
* 设编号为1,2,3.....n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,
* 它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列
*
*/
public class JosephuSample {
/*
* 1.先设置一个有n个结点的环形单链表
* 2.解决问题
* 3.打印
*/
private int size = 0;
private Node head = null;
private int[] leaveTheTeam = null; //用来存放出列学生的编号
/*
* 结点个数
*/
public int getSize(){
return size;
}
/*
* 加入结点
*/
public void LinkAdd(int n){
Node tmp = null;
while (!(size == n)) {
if(size == 0){
head = new Node(++size); //编号为1
head.setNext(head); //循环单链表
tmp = head;
}else {
tmp.setNext(new Node(++size));
tmp.getNext().setNext(head);
tmp = tmp.getNext();
}
}
}
/*
* 约瑟夫问题的核心代码
* k代表从那个人开始数
*/
public void coreCode(int k,int m){
//判断k的值
if(k < 1 || k > size){
System.out.println("学生编号不存在!!!");
return;
}
int i = 0; //编号
int j = 0; //数组leaveTheTeam的下标
leaveTheTeam = new int[size]; //这里注意不能在程序开头就new对象,否则会报下标越界异常
Node tmp = head;
Node pre_tmp = null; //用来存放tmp的前一个结点
for (int l = 1; l < k; l++) {
tmp = tmp.getNext();
}
while (tmp.getNext() != tmp) {
i++; //刚开始编号从1开始往后数
if(i % m == 0){
pre_tmp.setNext(tmp.getNext());
leaveTheTeam[j++] = tmp.getId();
i = 0; //表示下一轮又从下一个结点开始,编号为1
}
pre_tmp = tmp;
tmp = tmp.getNext();
}
leaveTheTeam[j] = tmp.getId();
}
/*
* 打印
*/
public void print(){
Node tmp = head;
for (int i = 1; i <= size; i++) {
System.out.println(tmp.toString());
tmp = tmp.getNext();
}
}
public void print2(){
for (int i = 0; i < leaveTheTeam.length; i++) {
System.out.println(leaveTheTeam[i]);
}
}
}
Test类
package com.josephu.test;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
JosephuSample j = new JosephuSample();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入人数:");
int n = scanner.nextInt();
j.LinkAdd(n);
j.print();
System.out.println("\n********************\n***************");
System.out.println("请输入k的值:");
int k = scanner.nextInt();
System.out.println("请输入m的值:");
int m = scanner.nextInt();
j.coreCode(k, m);
j.print2();
}
}
结果为:
请输入人数:
10
Node [id=1]
Node [id=2]
Node [id=3]
Node [id=4]
Node [id=5]
Node [id=6]
Node [id=7]
Node [id=8]
Node [id=9]
Node [id=10]
********************
***************
请输入k的值:
10
请输入m的值:
3
2
5
8
1
6
10
7
4
9
3