1. 程式人生 > >遞迴解決全排列生成演算法

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

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                排列:從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
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述