1. 程式人生 > >n的全排列遞迴演算法

n的全排列遞迴演算法

思路:

可以通過遞迴的方法把n的全排列問題轉化為n-1的全排列問題,逐漸推導到一個數字的全排列,顯然一個數字的全排列方式只有一種,下面就展示實現該過程的實現程式碼:

#include <iostream>
using namespace std;

void swap(int &a,int &b){
	int temp=a;
	a=b;
	b=temp;
}

void pai_xu(int a[],int m,int n){
	if(m==n){
		for(int i=1;i<=n;i++){
			cout<<a[i];
		}
		cout<<endl; 
	}
	else{
		for(int i=m;i<=n;i++){
			swap(a[i],a[m]);
			pai_xu(a,m+1,n);
			swap(a[i],a[m]);
		}
	}
}

int main(){
	int n,m=1,a[10];
	cin>>n;
	for(int i=1;i<=n;i++){
		a[i]=i;
	}
	pai_xu(a,m,n);
	return 0;
}

下面對程式碼進行解釋:

for(int i=m;i<=n;i++){
			swap(a[i],a[m]);
			pai_xu(a,m+1,n);
			swap(a[i],a[m]);
		}

在這一部分程式碼是整個程式的核心部分,很多人都是對這裡有疑問,在這部分中可以這樣理解,m代表著數列的開頭,a[i]和a[m]交換既是由a[i]所對應的數字打頭陣,由於有for迴圈的存在,顯然1-n都會有機會打頭陣,接下來的遞迴呼叫就是把n的全排列問題轉化為n-1的全排列問題,然後逐步推導,一直到m=n時可以輸出第一個排列,這時候程式就會執行上面語句段的第二個交換語句,這個語句的作用是要把原來交換了的排列恢復,讓前面的語句再換一個數字打頭陣接著又反覆進行。

注意:把m理解為數列的開頭,上面那句和a[m]交換,理解為把哪個數字換到開頭位置,後面的交換理解為換開頭數字前恢復排列的作用。