1. 程式人生 > >全排列演算法思想和實現

全排列演算法思想和實現

全排列的演算法思想和實現(C++版)

http://www.itmian4.com/forum.php?mod=viewthread&tid=3323

所謂全排列,就是將集合中元素的所有排列情況依次輸出。比如{1、2、3}的全排列為:123、132、213、231、312、321,共6種,滿足計算公式N!(N為集合中元素個數,不重複)。

當元素不重複時,全排列採用遞迴思想較容易實現,它的遞迴公式推導步驟類似:
1、要求得123的全排列,只需求得:1並上23的全排列(1 23, 1 32),2並上13的全排列(2 13, 2 31),3並上12的全排列(3 12 321)。
2、對於23的全排列,只需求得2並上3的全排列,3並上2的全排列。步驟1中13、12的全排列也類似。


3、對於3的全排列或者2的全排列,就是它們的本身。遞迴結束。

遞迴實現不重複元素全排列演算法的實現程式碼(C++)如下:

//交換a和b
void Swap(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}
 
//全排列函式。list:待排元素列表,start:起始位置下標,end:最後一個有效元素的下一個下標。
void Permutation(int start, int end, int list[])
{
    int i;
    if (start >= end) //遞迴結束,列印當前這次全排列結果,返回。
    {
        for (i = 0; i < end; i++)
        {
            printf("%d ", list[i]);
        }
        printf("\n");
        return;
    }
    //對於給定的list[start...end],要使區間中每一個元素都有放在第一位的機會,
    //然後開始遞迴呼叫自身,得到list[start+1...end]的全排列。
    for (i = start; i < end; i++) 
   {
       Swap(&list[i], &list[start]); //交換元素,使每一個元素都有放在第一位的機會。
        Permutation(start+1, end, list); //遞迴呼叫
        Swap(&list[i], &list[start]); //恢復原始的list,不影響下次遞迴呼叫。
    }
}
#include <iostream>
using namespace std;
 
int main()
{
    int a[] = {1, 2, 3};
    Permutation(0, 2, a);
    return 0;
}