遞迴解決全排列產生演算法

來源:互聯網
上載者:User
排列:從n個元素中任取m個元素,並按照一定的順序進行排列,稱為排列;

全排列:當n==m時,稱為全排列;

比如:集合{ 1,2,3}的全排列為:{ 1 2 3} { 1 3 2 }{ 2 1 3 }{ 2 3 1 }{ 3 2 1 }{ 3 1 2 } 方法一:我們可以將這個排列問題畫成圖形表示,即排列枚舉樹,比如為{1,2,3}的排列枚舉樹,此樹和我們這裡介紹的演算法完全一致;演算法思路:(1)n個元素的全排列=(n-1個元素的全排列)+(另一個元素作為首碼);(2)出口:如果只有一個元素的全排列,則說明已經排完,則輸出數組;(3)不斷將每個元素放作第一個元素,然後將這個元素作為首碼,並將其餘元素繼續全排列,等到出口,出口出去後還需要還原數組;
public class Test {public static int arr[] = new int[]{1,2,3};public static void main(String[] args) {perm(arr,0,arr.length-1);}private static void swap(int i1, int i2) {int temp = arr[i2];arr[i2] = arr[i1];arr[i1] = temp;}/** * 對arr數組中的begin~end進行全排列 *  * 比如: * arr = {1,2,3} *  第一步:執行 perm({1,2,3},0,2),begin=0,end=2; *  j=0,因此執行perm({1,2,3},1,2),begin=1,end=2; *  j=1,swap(arr,0,0)-->arr={1,2,3},  perm({1,2,3},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{1,2,3} *   swap(arr,1,1) --> arr={1,2,3}; *   j=2,swap(arr,1,2)-->arr={1,3,2},  perm({1,3,2},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{1,3,2} *   swap(arr,2,1) --> arr={1,2,3}; *   j=1,swap(arr,0,1) --> arr={2,1,3},  perm({2,1,3},1,2),begin=1,end=2; *   j=1,swap(arr,1,1)-->arr={2,1,3}   perm({2,1,3},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{2,1,3} *   swap(arr,1,1)--> arr={2,1,3}; *   j=2,swap(arr,1,2)後 arr={2,3,1},並執行perm({2,3,1},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{2,3,1} *   swap(arr,2,1) --> arr={2,1,3}; *   swap(arr,1,0)  --> arr={1,2,3} *   j=2,swap(arr,2,0) --> arr={3,2,1},執行perm({3,2,1},1,2),begin=1,end=2; *   j=1,swap(arr,1,1) --> arr={3,2,1} , perm({3,2,1},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{3,2,1} *   swap(arr,1,1) --> arr={3,2,1}; *   j=2,swap(arr,2,1) --> arr={3,1,2},並執行perm({2,3,1},2,2),begin=2,end=2; *   因為begin==end,因此輸出數組{3,1,2} *   swap(arr,2,1) --> arr={3,2,1}; *   swap(arr,0,2) --> arr={1,2,3} *    * @param arr * @param begin  * @param end */public static void perm(int arr[], int begin,int end) {if(end==begin){//一到遞迴的出口就輸出數組,此數組為全排列for(int i=0;i<=end;i++){System.out.print(arr[i]+" ");}System.out.println();return;}else{for(int j=begin;j<=end;j++){swap(begin,j);//for迴圈將begin~end中的每個數放到begin位置中去perm(arr,begin+1,end);//假設begin位置確定,那麼對begin+1~end中的數繼續遞迴swap(begin,j);//換過去後再還原}}}}
方法二:
public class Test2 {public static int arr[] = new int[]{0,0,0};public static void main(String[] args) {perm(3);}/** * 數組變化過程: * 3 0 0 * 3 2 0 * 3 2 1 * 3 2 0 * 3 0 0 * 3 0 2 * 3 1 2 * 3 0 2 * 3 0 0 * 0 0 0 * 0 3 0 * 2 3 0 * 2 3 1 * 2 3 0 * 0 3 0 * 0 3 2 * 1 3 2 * 0 3 2 * 0 3 0 * 0 0 0 * 0 0 3 * 2 0 3 * 2 1 3 * 2 0 3 * 0 0 3 * 0 2 3 * 1 2 3 * 0 2 3 * 0 0 3 * 0 0 0 * @param m */private static void perm(int m) {if(m==0){for(int i=0;i<arr.length;i++){System.out.print(arr[i]+" ");}System.out.println();return;}else{for(int i=0;i<arr.length;i++){if(arr[i]==0){arr[i] = m;perm(m-1);arr[i] = 0;}}}}}
參考文獻:1.全排列的遞迴演算法實現   李盤榮2.全排列遞迴演算法在演算法教學中的重要性  吳素萍3.排序演算法與全排列產生演算法研究 陳衛東, 鮑蘇蘇論文:http://yunpan.cn/lk/05qsom5mle

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.