約瑟夫問題是個有名的問題:
N個人圍成一圈,從第一個開始報數,第M個將被殺掉,最後剩下一個,其餘人都將被殺掉。例如N=6,M=5,被殺掉的人的序號為5,4,6,2,3。最後剩下1號。
代碼如下:
/** * 約瑟夫問題 * @author yxh * */public class Ysf {public void operate(int nump,int index,int start){if(nump<start){System.out.println("開始數不能大於總人數");return;}if(index<=0){System.out.println("index值必須大於0");return;}LinkNode ln = new LinkNode();int count =nump;//記錄//首先產生一個鏈表根據給定的人數for(int i=1;i<=nump;i++){ln.add(i);}//然後從start位置開始數數數了index次後停止此時的節點出列Node node = ln.findNode(start);//從此節點開始數數System.out.println("從"+node.getData()+"開始");while(true){for(int j =1;j<index;j++){if(node==null){node=ln.getHead();}else{node=node.getNextNode();if(node==null)node=ln.getHead();}} if(node!=null){ System.out.println("刪除:"+node.getData()); ln.deleteNode(node.getData()); ln.printNode(); count--;if(count==0){ln.printNode();if(node!=null)System.out.println("約瑟夫數是:"+node.getData());break;} node=node.getNextNode(); if(node==null)node=ln.getHead(); System.out.println("再從:"+node.getData()+"開始"); }}}public static void main(String[] args){Ysf yf = new Ysf();yf.operate(6, 5, 1);}}
LinkNode類:
/** * 建立一個鏈表 * 來實現約瑟夫問題 */class LinkNode{private Node head;//前端節點public Node getHead() {return head;}public void setHead(Node head) {this.head = head;}public void add(int data){Node node = new Node(data);if(head==null){head=node;}else{head.addNode(node);}}public Node findNode(int data){if(head==null){return null;}else{return head.find(data);}}public void deleteNode(int data){if(head!=null){if(head.getData()==data){head = head.getNextNode();}else{if(head.getNextNode()!=null){head.getNextNode().delete(head, data);}}}}public void printNode(){if(head!=null){head.print();}}}
最後是節點類:
public class Node {private int data;//資料public int getData() {return data;}public void setData(int data) {this.data = data;}private Node nextNode;//下一個節點public Node getNextNode() {return nextNode;}public void setNextNode(Node nextNode) {this.nextNode = nextNode;}public Node(int data){this.data=data;}//添加節點到鏈表public void addNode(Node node){if(this.nextNode!=null){this.nextNode.addNode(node);}else{this.nextNode=node;}}//尋找節點public Node find(int data){if(this.data==data){return this;}else{if(this.nextNode!=null){return this.nextNode.find(data);}}return null;}//刪除節點public void delete(Node preNode,int data){if(this.data==data){preNode.nextNode=this.nextNode;}else{if(this.nextNode!=null){this.nextNode.delete(this, data);}}}//輸出節點資訊public void print(){System.out.print(this.data+"---->");if(this.nextNode!=null){this.nextNode.print();}}}
一下是測試輸出的結果:
從1開始
刪除:5
1---->2---->3---->4---->6---->再從:6開始
刪除:4
1---->2---->3---->6---->再從:6開始
刪除:6
1---->2---->3---->再從:1開始
刪除:2
1---->3---->再從:3開始
刪除:3
1---->再從:1開始
刪除:1
約瑟夫數是:1
以上純屬於自己的實現,如有不對的地方還望大家指正。多謝了。