約瑟夫環問題 java程式碼實現(高效率)
阿新 • • 發佈:2019-01-28
<pre name="code" class="java">//約瑟夫問題 package com.test; public class test { public static void main(String[] args) { CycLink cycLink= new CycLink(5,2,3); } } class ChildNode{ int Num;//編號 ChildNode nextChildNode=null;//指向下一個結點 ChildNode preChildNode=null; public ChildNode(int num){ this.Num=num; } } class CycLink{//環形連結串列 //先定義一個指向連結串列第一個結點的引用,指向第一個結點的引用,不能動 ChildNode TofirstChildNode=null; ChildNode temp=null; int len=0;//共有多少個結點 int k=0;//從第幾個人開始數數 int m=0;//數m下 int n=1;//第n個人出局 //設定連結串列大小 public CycLink(int len,int k,int m){ this.len=len;//設定環形連結串列大小 this.k=k;//設定從第幾個人開始數數 this.m=m;//設定數m下 creatLink(); showLink(); play(); } //開始約瑟夫規則遊戲 private void play(){ ChildNode cursor=this.TofirstChildNode; //1.先開始找到開始數數的人 for(int i=1;i<k;i++){ cursor=cursor.nextChildNode; } while(this.len!=1){ //2.數m下,找到了要刪除的結點 for(int j=1;j<m;j++){ cursor=cursor.nextChildNode; //其實沒人引用了,那麼過會兒就會被GC回收 } //3.將數到m的結點,退出圈 System.out.println("第"+this.n+"次出局的人編號是:"+cursor.Num); cursor.preChildNode.nextChildNode=cursor.nextChildNode;//刪除操作 cursor.nextChildNode.preChildNode=cursor.preChildNode;//刪除操作 //讓cursor指向下一個開始數數的人,這個動作很重要,不然遊標就不動了 cursor=cursor.nextChildNode; this.len--;//出圈一個人, this.n++; } //最後一個剩下的結點 System.out.println("最後還在桌子上坐著的人編號:"+cursor.Num); } //初始化環形連結串列 private void creatLink(){ for(int i=1;i<=len;i++){ if(i==1){ //建立第一個結點 ChildNode ch=new ChildNode(i); this.TofirstChildNode=ch; temp=ch; } else{ //建立最後一個結點 if(i==len){ ChildNode ch=new ChildNode(i); temp.nextChildNode=ch; ch.preChildNode=temp; temp=ch; temp.nextChildNode=this.TofirstChildNode; this.TofirstChildNode.preChildNode=ch; } else{ //繼續建立結點 ChildNode ch=new ChildNode(i); temp.nextChildNode=ch; ch.preChildNode=temp; temp=ch; } } } } //列印環形連結串列 private void showLink(){ //定義一個遊標 ChildNode cursor=this.TofirstChildNode; do{ System.out.println("參員編號為:"+cursor.Num); cursor=cursor.preChildNode; } while(cursor!=this.TofirstChildNode); } }
執行結果: