全排列遞迴實現
阿新 • • 發佈:2019-02-03
#include <iostream> using namespace std; void swap(int &a,int &b){ int temp=a; a=b; b=temp; } void perm(int list[],int low,int high){ if(low==high){ //當low==high時,此時list就是其中一個排列,輸出list for(int i=0;i<=low;i++) cout<<list[i]; cout<<endl; }else{ for(int i=low;i<=high;i++){//每個元素與第一個元素交換 swap(list[i],list[low]); perm(list,low+1,high); //交換後,得到子序列,用函式perm得到子序列的全排列 swap(list[i],list[low]);//最後,將元素交換回來,復原,然後交換另一個元素 } } } int main() { int list[]={1,2,3}; perm(list,0,2); return 0; }
我們把上面全排列的方法歸納一下,基本上就是:任意選一個數(一般從小到大或者從左到右)打頭,對後面的n-1個數進行全排列。聰明的讀者應該已經發現,這是一個遞迴的方法,因為要得到n-1個數的全排列,我們又要先去得到n-2個數的全排列,而出口是隻有1個數的全排列,因為它只有1種,為它的本身。寫成比較規範的流程:
1.開始for迴圈。
2.改變第一個元素為原始陣列的第一個元素(什麼都沒做)。
3.求第2個元素到第n個元素的全排列。
4.要求第2個元素到第n個元素的全排列,要遞迴的求第3個元素到第n個元素的全排列。......
5.直到遞迴到第n個元素到第n元素的全排列,遞迴出口。
6.將改變的陣列變回。
7.改變第一個元素為原始陣列的第二個元素。
(注:理論上來說第二次排列時才改變了第一個元素,即第6步應該此時才開始執行,但由於多執行一次無義的交換影響不大,而這樣使得演算法沒有特殊情況,更容易讀懂,如果一定要省時間可以把這步寫在此處,這種演算法我在下文中便不給出了,讀者可以自己寫。)5.求第2個元素到第n個元素的全排列。
6.要求第2個元素到第n個元素的全排列,要遞迴的求第3個元素到第n個元素的全排列。......
5.直到遞迴到第n個元素到第n元素的全排列,遞迴出口。6.將改變的陣列變回。......
8.不斷地改變第一個元素,直至n次使for迴圈中止。