全排列问题

全排列问题定义:

一般地,从n个不同元素中取出mmn)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列(Sequence,Arrangement, Permutation)

n个不同元素全部取出的一个排列,叫做n个不同元素的一个全排列。这是在排列数公式中,m=n,即有:
Ann=n·(n-1)·(n-2)··3·2·1
 
举例:
输入:
1
2 3


输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 3 1 2

设R={r1,r2,r3...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)由(ri)Perm(R1),(r2)Perm(R2)....(rn)Perm(Rn)构成。

依次递归定义,可设计产生Perm(R)的递归算法如下

 

void swap(int &a,int &b)
{
    int c;
    c=a;
    a=b;
    b=c;
}
void Perm(int a[],int k,int m)
{//产生a[k:m]的所有排列
    if(k==m)
    {   //只剩下1个元素
        for(int i=0; i<=k; i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    else//还有多个元素待排列,递归产生排列。
    {
        for(int i=k; i<=m; i++)
        {
            swap(a[i],a[k]); //替换
            Perm(a,k+1,m);
            swap(a[i],a[k]);//恢复
        }
    }
}

 

算法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是调用于交换两个变量值的函数。

 

posted on 2013-04-20 19:53  dztgc  阅读(859)  评论(0编辑  收藏  举报