约瑟夫环问题:
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。
从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;
依此规律重复下去,直到圆桌周围的人全部出列。
基本要求:用不带头结点的单循环连表作为数据元素的存储结
结点个数:8。即8个结点的编号1,2,3,4,5,6,7,8
随机报数值m = 2.
package cn.ls.ring.test;
/**
*
*结点类
*/
public class Node {
int code; //结点值
Node next; //下一个结点
public Node() {
super();
}
public Node(int code) {
super();
this.code = code;
}
Node(int code, Node nextVal){
this.code = code;
this.next = nextVal;
}
public boolean equals(Node node) {
return code == node.code;
}
}
package cn.ls.ring.test;
/**
*
*约瑟夫环类
*/
public class JesephTest {
//头指针
Node head;
//尾指针
Node rear;
//当前指针
Node current;
int size;
/**
* 删除
* @param m 随机报数值 逐个删除所有结点.
*/
private void delete(int m){
//从头结点开始.
current = head;
while(size > 0){
//寻找第m个
for (int i = 1; i<m; i++){
current = current.next;
}
//输出被删除结点编号
System.out.print(current.next.code+" ");
//被删结点脱链
current.next = current.next.next;
//从被删结点的下一个开始循环.
current = current.next;
size -- ;
}
head = rear = current = null;
}
/**
* 插入
* @param i 编号
* @param obj 元素
*/
private void insert(int i, Node obj){
//定位
index(i-1);
//设置第一次插入的指针值
if(size == 0) head = rear = current = obj;
//新节点加入连表
obj.next = current.next;
current.next = obj;
//构成循环连表
if(current.equals(rear)){
obj.next = head;
rear = obj;
}else{
rear.next = head;
}
size ++;
}
/**
* 定位
* @param i 编号
*/
private void index(int i) {
if (i == -1)return ;
current = head;//从头指针开始定位
int j=0;
while(current != null && j < i){
current = current.next;
j++;
}
}
public static void main(String[] args) {
JesephTest je = new JesephTest();
je.insert(0, new Node(1));
je.insert(1, new Node(2));
je.insert(2, new Node(3));
je.insert(3, new Node(4));
je.insert(4, new Node(5));
je.insert(5, new Node(6));
je.insert(6, new Node(7));
je.insert(7, new Node(8));
Node curr = je.head;
System.out.println("构建循环连表:");
//查看循环连表是否构建完成
for (int i = 0; i<je.size * 2 ; i++){
System.out.print(curr.code+" ");
curr = curr.next;
}
System.out.println("\r依次被删结点编号为:");
je.delete(2);//随机报数值 = 2
}
}
结果为:
测试是否构成循环链表:
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
依次被删结点编号为:
3 6 1 5 2 8 4 7