全排列問題的遞歸算法(Perm)


題目】設計一個遞歸算法生成n個元素{r1,r2,…,rn}的全排列。

算法講解

設R={r1,r2,…,rn}是要進行排列的n個元素,Ri=R-{ri}。
集合X中元素的全排列記為perm(X)。
(ri)perm(X)表示在全排列perm(X)的每一個排列前加上前綴得到的排列。
R的全排列可歸納定義如下:
當n=1時,perm(R)=(r),其中r是集合R中唯一的元素;
當n>1時,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)構成。
實現思想:將整組數中的所有的數分別與第一個數交換,這樣就總是在處理后n-1個數的全排列。

示例

當n=3,並且E={a,b,c},則:
perm(E)=a.perm({b,c}) + b.perm({a,c}) + c.perm({a,b})
perm({b,c})=b.perm(c) + c.perm(b)
a.perm({b,c})=ab.perm(c) + ac.perm(b)
=ab.c + ac.b=(abc, acb)

核心代碼

template<class Type>
void Perm(Type list[],  int k, int m )
{ //產生[list[k:m]的所有排列
    if(k==m)
     {  //只剩下一個元素
         for (int i=0;i<=m;i++) 
     cout<<list[i];
         cout<<endl;
    }
    else  //還有多個元素待排列,遞歸產生排列
       for (int i=k; i<=m; i++)
        {
           swap(list[k],list[i]);
           Perm(list,k+1,m);   
           swap(list[k],list[i]);         
         }
}

完整代碼

#include <iostream>
#include <algorithm>

using namespace std;

template<class Type>
void Perm(Type list[],  int k, int m )
{ //產生[list[k:m]的所有排列
    if(k==m)
     {  //只剩下一個元素
         for (int i=0;i<=m;i++) 
     cout<<list[i];
         cout<<endl;
    }
    else  //還有多個元素待排列,遞歸產生排列
       for (int i=k; i<=m; i++)
        {
           swap(list[k],list[i]);
           Perm(list,k+1,m);   
           swap(list[k],list[i]);         
         }
}

int main() {
    
    char s[]="abc";
    Perm(s,0,2);

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM