给定n≥1个元素的集合,问题是输出这个集合中所有元素的排列。例如:如果集合是{ a, b, c },那么,这个集合元素的全排列为:{ (a,b,c), (a,c,b), (b,a,c), (b,c,a), (c,a,b), (c,b,a) }。容易看出,如果给定的集合中有n个元素,那么就有n!个不同的排列。通过下面的例子可以看出算法的简单思路:集合有四个元素,(a,b,c,d),答案可以这样构造:
1. a后接(b, c, d)的排列
2. b后接(a, c, d)的排列
3. c后接(a, b, d)的排列
3. d后接(a, b, c)的排列
可见,如果能生成n – 1个元素的全排列,就能生成n个元素的全排列。
设定3个参数,分别是存放元素的数组、参与排列的第一个元素的位置以及数组中元素的个数:
perm(a,k,n),调用参数:a,0,n。
voidperm (char *a, const intk,constintn) {
//n 是数组a的元素个数,生成a[k],…,a[n-1]的全排列
inti;
if (k = = n-1) { // 终止条件,输出排列
for( i=0;i<n;i++) cout << a[i]<< “ ”; // 输出包括前
// 缀,以构成整个问题的解
cout << endl;
}
else { // a[k],…,a[n-1] 的排列大于1,递归生成
for (i= k; i < n;i++) {
char temp = a[k]; a[k]= a[i]; a[i]= temp; //交换a[k]
// 和 a[i]
perm(a,k+1,n); // 生成 a[k+1],…,a[n-1]的全排列
temp= a[k]; a[k]= a[i]; a[i]= temp;
//再次交换a[k] 和a[i] , 恢复原顺序
}
} //else结束
} // perm结束