什么是约瑟夫问题
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k(1<=k<=n)的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
首先定义一个结点
public class Node {
//编号
int no;
String name;
//下一个结点
Node next;
public Node() {
}
public Node(int no, String name) {
this.no = no;
this.name = name;
}
public Node(int no) {
this.no = no;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
接下来定义单向环形链表的主要功能
public class CirLinkedList {
private Node head;
CirLinkedList(){
Node node = new Node();
node.no=-1;
node.name="";
//环形链表
head=node;
node.next=head;
}
void insert(Node node){
//遍历至链表的结尾
Node temp=head;
while(temp.next!=head){
temp=temp.next;
}
node.next=temp.next;
temp.next=node;
}
void delete(int no){
//遍历至链表的结尾
Node temp=head;
while(temp.next!=head){
//条件满足说明就有数据
if(temp.next.no==no){
System.out.println(temp.next);
temp.next=temp.next.next;
break;
}
temp=temp.next;
}
}
void soleJosephu(int k,int m){
//有数据才遍历
if(head.next!=head){
//如果头结点的next指向自己说明没有数据了
int count=0;
boolean flat=true;
Node temp=head;
while(head.next!=head){
temp=temp.next;
if(temp==head){
continue;
}
else{
if(count==m&&!flat)
count=0;
count++;
}
if(count==k&&flat){
count=1;
flat=false;
}
if(count==m&&!flat){
int delNo=temp.no;
//删除之前要移动指针
//temp=temp.next;
//count=1;
delete(delNo);
}
}
}
}
}
让我们看下测试类
CirLinkedList list = new CirLinkedList();
for (int i = 1; i < 10; i++) {
Node n = new Node(i);
list.insert(n);
}
int k=1;
int m= 4;
list.soleJosephu(k,m);
看下测试数据的结果