递归、分治-排列问题

版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/83686885

之前用暴力求解法求结果全排列,现在我们用分治的方法重新求解一遍。

输入:数组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是用与交换两个变量值的内联函数。

猜你喜欢

转载自blog.csdn.net/baidu_38304645/article/details/83686885
今日推荐