之前用暴力求解法求结果全排列,现在我们用分治的方法重新求解一遍。
输入:数组P大小n,数组P中的各个元素。
输出:数组P的所有全排列。
运行结果:
设R = {r1,r2,..rn}是要进行排列的n个元素, Ri = R - {ri}.集合X中元素的全排列记为Perm(X).(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。R的全排列可归纳定义如下:
当n=1时,Perm(R) = (r),其中r是集合R中唯一的元素;
当n>1时,Perm(R)由 (r1)Perm(R1),(r2)Perm(R2),...,(rn)Perm(Rn)构成。
template <class Type> //模板函数
void Perm(Type list[], int k, int m)
{
//产生list[k, m]的所有排列
int i;
if(k == m)
{
//只剩下一个元素
for(i = 0; i <= m; i++)
cout << list[i] << " ";
cout << endl;
}
else
{
//还有多个元素待排列,递归产生排列
for(i = k; i <= m; i++)
{
swap(list[k], list[i]);
Perm(list, k+1, m);
swap(list[k], list[i]);
}
}
}
算法Perm(list,k,m)递归地产生所有前缀是list[0:k-1],且后缀是list[k,:m]的全排列的全排列的所有排列。函数调用Perm(list,0,n-1)则产生list[0,n-1]的全排列。
在一般情况下,k<m,算法将list[k,m]中的每一个元素分别与list[k]中的元素交换。然后递归的计算list[k+1:m]的全排列,并将计算结果作为list[0:k]的后缀。算法中Swap是用与交换两个变量值的内联函数。