1. 程式人生 > >全排列(Java實現)

全排列(Java實現)

廢話少說,直接上程式碼:

public static void permutation(char[]ss,int i){  
        if(ss==null||i<0 ||i>ss.length){//1  
            return;  
        }
        
        if(i==ss.length-1){//2  
            System.out.println(new String(ss));  
        }else{  
            for(int j=i;j<ss.length;j++){//3  
                char temp=ss[j];//交換字首,使之產生下一個字首  
                ss[j]=ss[i];  
                ss[i]=temp;  
                permutation(ss,i+1);//4  
                temp=ss[j]; //將字首換回來,繼續做上一個的字首排列.//5  
                ss[j]=ss[i];  
                ss[i]=temp;  
            }   
        }  
    }  
    public static void main(String args[]){
    	permutation(new char[]{'a','b','c','d'},0);
    }

再談理解:

這裡採用的是遞迴的方法實現,註釋1不用多說,對要進行全排列的資料進行判空校驗。

這裡先看註釋3,從main方法進來之後會先道註釋3這部分的程式碼,此時i=0,j=0,(陣列內元素{'a','b','c','d'})

可以看到先是a和a交換了位置(相當於沒交換,但也算一種情況),然後進行遞迴呼叫,

從註釋4可以看到i+1,可以想到遞迴呼叫裡面就會依據當前已經交換了的狀態(此處a與a交換)繼續進行交換,

當然下一步遞迴呼叫交換b與b(i變成i+1了嘛),依次類推,但遞迴交換到最後會到註釋2的判斷,

發現此時i已經是陣列的最後一個元素下標了(即已經沒有後續元素給他交換),因此這樣就已經形成了一種排列,輸出排列。

好,第一次輸出結果輸出完了之後,終於有機會到達依次註釋5了,從上面結果分析,

第一次全排列輸出應該是a,b,c,d因為每一次都是和自己的位置做交換,

下面從第一個跳出遞迴的地方分析,

第一次跳出來的是c,此時i=2,j=2

(因為(i+1=陣列長度-1)之後就符合註釋2的判斷,形成一種排列,上面說過,最後一個元素已經沒有後續元素和他進行交換),

跳出遞迴後,就在註釋5處把交換過的字首換回來(雖然這裡無影響)

然後j++之後,然後繼續for迴圈,此時i=2,j=3,

此時終於交換了不同的元素了!交換的是c與d,然後也是遞迴呼叫,但是發現遞迴下去

也是達到了i+1=陣列長度-1 符合註釋2的判斷,所以此時輸出a,b,d,c的排列,好,這裡輸出完之後,也相應地結束了關於c這一次的遞迴呼叫了, 就退到了b(即i=1,j=1)其實到了這裡就和上面的一樣,繼續執行迴圈體,i=1,j=2,然後交換字首,

即b與c交換,然後繼續遞迴呼叫,其實就是在這樣的字首下進行剛剛講過的遞迴過程,

當然注意退出遞迴時,要把之前的交換過的字首換回來,以便下一次字首交換。