1. 程式人生 > >順序表之約瑟夫環(josephus)

順序表之約瑟夫環(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)
         被赦免者是:C

4.實現過程分析

     成員變數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),因此我們需要尋找其他的結構來實現,後面我們會隨著資料結構的深入學習,嘗試用其他演算法求解並進行比較,如下是用順序表求解時消耗的時間

public 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");
		
	}
程式執行時間:32ms