一、问题描述:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3, 最后剩下1号
二、节点类
package com.justin.josephus;
/**
*
* Author: Justin Hu
* Create Date: Apr 24, 2014
* Description:
*
*/
public class JosephusNode {
public int data;
public JosephusNode next;
public JosephusNode(){
this(0);
}
public JosephusNode(int data){
this.data = data;
}
}
二、约瑟夫环实现类
package com.justin.josephus;
/**
*
* Author: Justin Hu
* Create Date: Apr 24, 2014
* Description: 约瑟夫环实现类
*
*/
public class JosephusLink {
private JosephusNode header;
public JosephusLink(){
header = null;
}
public JosephusLink(JosephusNode node){
header = node;
}
/**
* 构造由nodeNum个节点组成的单向循环链表
* @param nodeNum
*/
public JosephusLink(int nodeNum){
int nodeSeq = 1;
JosephusNode rear, tempNode;
if(nodeNum > 0){
header = new JosephusNode(nodeSeq);
header.next = header;
rear = header;
while(nodeSeq < nodeNum){
nodeSeq++;
tempNode = new JosephusNode(nodeSeq);
tempNode.next = header;
rear.next = tempNode;
rear = tempNode;
}
}
}
/**
* 解约瑟夫环
* @param startIndex 开始节点序号
* @param skipNum 解约瑟夫环过程中需要路过的节点数目
*/
public void playJosephusLoop(int startIndex, int skipNum){
int i = 0;
JosephusNode tempNode = header;
while(i < startIndex - 1){
tempNode = tempNode.next;
i++;
}
while(tempNode.next != tempNode){//多于一个节点时循环
i = 0;
while(i < skipNum){//计数
tempNode = tempNode.next;
i++;
}
delNextOfGivenNode(tempNode);
tempNode = tempNode.next;
outputNodeList();
}
}
/**
* 删除指定节点的下一个节点
* @param node
*/
public void delNextOfGivenNode(JosephusNode node){
JosephusNode tempNode = node.next;
System.out.print("delete: " + tempNode.data + " ");
if(tempNode == header){//如果指定节点的下一节点是头节点,该节点被删除前需要先确定新的头节点
header = tempNode.next;
}
node.next = tempNode.next;
}
/**
* 输入节点链表中存在的所有元素
*/
public void outputNodeList() {
JosephusNode tempNode = header;
System.out.print("Elements after detlete on element: ");
do {
System.out.print(tempNode.data + " -> ");
tempNode = tempNode.next;
} while (tempNode != header);
System.out.println();
}
}
三、测试类
package com.justin.josephus;
import org.junit.Test;
/**
*
* Author: Justin Hu
* Create Date: Apr 24, 2014
* Description: 约瑟夫环测试类
*
*/
public class JosephusLinkTest {
@Test
public void playJosephusLoop(){
int nodeNum = 5, skipNum = 2, startIndex = 1;
JosephusLink josephusLink = new JosephusLink(nodeNum);
josephusLink.outputNodeList();
josephusLink.playJosephusLoop(startIndex, skipNum);
}
}