約瑟夫環是一個數學的應用問題:已知n我的(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號爲k的人開始報數,數到m的那我的出列;他的下一我的又從1開始報數,數到m的那我的又出列;依此規律重複下去,直到圓桌周圍的人所有出列。一般解決這類問題時咱們把編號從0~n-1,最後結果+1即爲原問題的解。java
1.用單鏈表實現node
package com.cws.joseph; import java.util.Date; public class JosephCircle { /** * 做者: * 功能:約瑟夫環 * 用單鏈表實現 */ public static void main(String[] args){ NodeLink link = new NodeLink(); // link.setLen(5); System.out.println("開始建立"+new Date()); link.createLink(1000000); System.out.println("建立結束"+new Date()); // link.test(); link.setK(1000); link.setM(1000); System.out.println("開始遊戲"+new Date()); link.play(); System.out.println("遊戲結束"+new Date()); } } class Node{ private long no; private Node nextNode; public long getNo() { return no; } public void setNo(long no) { this.no = no; } public Node getNextNode() { return nextNode; } public void setNextNode(Node nextNode) { this.nextNode = nextNode; } public Node(long no){ this.no=no; } } class NodeLink{ private Node firstNode; private Node temp; private Node temp2; private long len; private long k;//第幾我的開始報數 private long m;//每次報多少數 public Node getTemp2() { return temp2; } public void setTemp2(Node temp2) { this.temp2 = temp2; } public long getK() { return k; } public void setK(long k) { this.k = k; } public long getM() { return m; } public void setM(long m) { this.m = m; } public void createLink(long len){ this.len = len; for(long i = 1;i<=len;i++){ if(i==1){ Node node = new Node(i); firstNode = node; temp = node; }else if(i != 1 && i != len){ Node node = new Node(i); temp.setNextNode(node); temp = node; }else{ Node node = new Node(i); temp.setNextNode(node); temp = node; temp.setNextNode(firstNode); } } } public void test(){ for(long i =0;i<this.len;i++){ if(i==0){ temp=firstNode; } System.out.println(temp.getNo()); temp = temp.getNextNode(); } } public void play(){ temp = firstNode; //先找到第一個報數的人 for(long i = 1;i<k;i++){ temp = temp.getNextNode(); } while(this.len != 1){ //找到要出列的人 for(long i=1;i<m;i++){ if(i==(m-1)){ temp2 = temp; } temp = temp.getNextNode(); } //讓要出列的人出列 temp2.setNextNode(temp.getNextNode()); temp = temp.getNextNode(); this.len--; } System.out.println("最後一個出列的是"+temp.getNo()); } public Node getFirstNode() { return firstNode; } public void setFirstNode(Node firstNode) { this.firstNode = firstNode; } public Node getTemp() { return temp; } public void setTemp(Node temp) { this.temp = temp; } public long getLen() { return len; } public void setLen(long len) { this.len = len; } }
2.用雙鏈表解決web
package com.cws.joseph; import java.util.Date; public class JosephCircle_2 { /** * 做者: * 功能:約瑟夫環 * 用雙向鏈表實現 */ public static void main(String[] args) { // TODO Auto-generated method stub DoubleLink doubleLink = new DoubleLink(); System.out.println("開始建立"+new Date()); doubleLink.createDoubleLink(1000000); System.out.println("建立結束"+new Date()); // doubleLink.testlast(); doubleLink.setK(1000); doubleLink.setM(1000); System.out.println("開始遊戲"+new Date()); doubleLink.play(); System.out.println("遊戲結束"+new Date()); } } class DoubleNode{ private long no; private DoubleNode lastNode; private DoubleNode nextNode; public long getNo() { return no; } public void setNo(long no) { this.no = no; } public DoubleNode getLastNode() { return lastNode; } public void setLastNode(DoubleNode lastNode) { this.lastNode = lastNode; } public DoubleNode getNextNode() { return nextNode; } public void setNextNode(DoubleNode nextNode) { this.nextNode = nextNode; } public DoubleNode(long no){ this.no = no; } } class DoubleLink{ private long len; private DoubleNode firstNode; private DoubleNode lastNode; private DoubleNode temp; private DoubleNode temp2; private long k;//第幾我的開始報數 public long getK() { return k; } public void setK(long k) { this.k = k; } public long getM() { return m; } public void setM(long m) { this.m = m; } private long m;//每次報多少數 public long getLen() { return len; } public void setLen(long len) { this.len = len; } public DoubleNode getFirstNode() { return firstNode; } public void setFirstNode(DoubleNode firstNode) { this.firstNode = firstNode; } public void createDoubleLink(long len){ this.len = len; for(long i=1;i<=len;i++){ if(i == 1){ DoubleNode doubleNode = new DoubleNode(i); firstNode = doubleNode; temp = doubleNode; temp2 = doubleNode; }else if(i !=1 && i !=len){ DoubleNode doubleNode = new DoubleNode(i); temp.setNextNode(doubleNode);//設置上個的下一個 temp = doubleNode;//移動到當前 temp.setLastNode(temp2);//設置當前個的上一個 temp2 = doubleNode; }else{ DoubleNode doubleNode = new DoubleNode(i); lastNode = doubleNode; temp.setNextNode(doubleNode);//設置上個的下一個 temp = doubleNode;//移動到當前 temp.setLastNode(temp2);//設置當前個的上一個 temp.setNextNode(firstNode);//設置最後一個的下一個爲第一個 temp=firstNode;//移動到第一個 temp.setLastNode(doubleNode);//設置第一個的上一個爲最後一個 } } } public void play(){ temp = firstNode; //先找到第一個報數的人 for(long i = 1;i<k;i++){ temp = temp.getNextNode(); } while(this.len != 1){ //找到要出列的人 for(long i=1;i<m;i++){ temp = temp.getNextNode(); } //讓要出列的人出列 // temp2.setNextNode(temp.getNextNode()); if(len != 2){ temp2 = temp.getLastNode(); temp = temp.getNextNode(); temp2.setNextNode(temp); temp.setLastNode(temp2); }else{ temp = temp.getNextNode(); temp.setLastNode(null); temp.setNextNode(null); } this.len--; } System.out.println("最後一個出列的是"+temp.getNo()); } public void testnext(){ for(long i =0;i<this.len;i++){ if(i==0){ temp=firstNode; } System.out.println(temp.getNo()); temp = temp.getNextNode(); } } public void testlast(){ for(long i=this.len;i>=1;i--){ if(i == this.len){ temp = lastNode; } System.out.println(temp.getNo()); temp = temp.getLastNode(); } } }