順序表之約瑟夫環(josephus)
1.問題描述
n個犯人站成一個圈,從第s個人開始數起,每數到第d個犯人,就拉出來斬了,然後再從下一個開始數d個,數到的人再處決,………………,直到剩下最後一個犯人就予以赦免。
2.演算法描述
建立一個具有n個元素的順序表物件list。
從第s個元素開始,依次計數,每數到d,就將對應的元素刪除。
重複計數並刪除元素,知道剩下一個元素。
3.演算法的java實現
程式執行結果package linearList; public class Josephus { private LList<String> list;//建立順序表,用來儲存元素 /* * 建立約瑟夫環並求解,指定其長度、起始位置、計數 */ public Josephus(int number,int start,int distance){ this.list = new SeqList<String>(number);//建立指定容量的的順序表 for(int i=0;i<number;i++){ this.list.add(new String((char)('A'+i)+""));//新增字串物件 } System.out.print("約瑟夫環("+number+","+start+","+distance+"),"); System.out.println(this.list.toString());//顯示字串 int index = start-1;//計數起始位置 while(this.list.length()>1){//只有在多餘一個物件時才執行刪除操作 index = (index+distance-1)%this.list.length(); System.out.print("刪除"+this.list.remove(index).toString()+","); System.out.println(this.list.toString()); } System.out.println("被赦免者是:"+list.get(0).toString()); } public static void main(String[] args) { new Josephus(5,1,2); } }
約瑟夫環(5,1,2),(A,B,C,D,E)
刪除B,(A,C,D,E)
刪除D,(A,C,E)
刪除A,(C,E)
刪除E,(C)
被赦免者是:C4.實現過程分析
成員變數list宣告為LList(線性表概括)介面的變數,宣告如下:
private LList<String> list;
list可被賦值為實現LList介面的類(線性表之順序表)的物件。即
this.list = new SeqList<String>(number);
index表示順序表元素符號,由於約瑟夫環是一個環形結構,所以順序表也要是環形的,這就要求計數時,index應該執行取餘操作,即
index = (index+distance-1)%this.list.length();
5.效率分析
由於涉及到新增和刪除操作,所以用順序表來實現約瑟夫環不是太理想,時間複雜度為O(n),因此我們需要尋找其他的結構來實現,後面我們會隨著資料結構的深入學習,嘗試用其他演算法求解並進行比較,如下是用順序表求解時消耗的時間
程式執行時間:32mspublic static void main(String[] args) { long startTime = System.currentTimeMillis(); for(int i=0;i<10;i++) new Josephus(5,1,2); long endTime = System.currentTimeMillis(); System.out.println("程式執行時間:"+(endTime-startTime)+"ms"); }