Java 用单向循环链表实现 约瑟夫问题

2020年6月6日重温代码:

public class LinkQueue {
Node head;
Node tail;
int size;
//造环
public Node createNodeCircle(int len){
if(len == 0) return null;
for(int i = 0 ; i < len;i++){
Node node = new Node(null,i);
if(i == 0){
node.next = node;
head = node;
tail = node;
}else{
node.next = tail.next;
tail.next = node;
tail = node;
}
}
return head;
}
// start 开始位置,deathNumber 死亡数字,playersNumber 玩家人数
    public int alive(int start,int deathNumber,int playersNumber){
Node node = createNodeCircle(playersNumber);
Node startNode = node;
for(int i = 0;i < start-1; i++){
startNode = startNode.next;
}
int count = 1;
while(startNode!=null && startNode.next!=startNode){
if(count == deathNumber-1){
System.out.println("death"+startNode.next.value);
startNode.next = startNode.next.next;
count = 1;
}else{
count++;
}
startNode = startNode.next;
}
return startNode.value;
}
public static void main(String[] args) {
LinkQueue l = new LinkQueue();
System.out.println(l.alive(2, 3, 7));
}
}
//之前的
public class lianbiao2 {
class Node{
Node next;
int number;
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node(int i) {
this.number = i;
}
public Node(Node next, int number) {
this.next = next;
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
public Node firsetnode;
public Node tempNode;
int len;
/**
* 造环的关键是:
* 再生成第一个Node的时候,让两个引用(firsetnode和tempNode)指向他,之后循环时,每次通过tempNode引用操作尾结点,将新生成的节点加上
* 当长度够后,将新生成的节点的 next 指向开始就一直没变的 firsetnode的引用,也就是指向了第一一个生成的节点,完成 环状
*/
public void setcrcle(int length){
for(int i=1;i<=length;i++){
Node node = new Node(i);
if(i==1){
firsetnode = node;
tempNode = node;
}else{
if(i != length){
tempNode.next= node;
tempNode = node;
}else{
tempNode.next=node;
node.next = firsetnode;
}
}
len++;
}
System.out.println(len);
}
public int play(int keillNumber){
return play(1,keillNumber);
}
/**
* 先找到开始节点。
* 从开始节点开启循环,遍历整个环,退出条件是,tempNode没有后续了 且 不等于自身
* 实现循环 后,当count等于死亡数字,直接删除下一个节点,count重新置1
*
*
* @param start 开始位置
* @param killNumber 死亡数字
* @return
*/
public int play(int start,int killNumber){
int count =1;
Node tempNode = firsetnode;
for(int i = 1;i<start;i++){
tempNode= firsetnode.next;//找到初始节点
}
while(tempNode.next != null && tempNode.next !=tempNode){
if(count != killNumber-1){
count++;
tempNode=tempNode.next;//实现循环
}else{
System.out.println("死的是"+tempNode.next.getNumber());
tempNode.next=tempNode.next.next;//直接删除下一个节点
tempNode= tempNode.next;//实现循环
count=1;
}
}
return tempNode.getNumber();
}
public static void main(String[] args) {
lianbiao2 l =new lianbiao2();
l.setcrcle(10);
System.out.println("存活的是"+l.play(2,5));;
}
}