經典演算法題2 遞迴和字典序的全排列演算法

2021-06-25 16:03:17 字數 2139 閱讀 7169

1,遞迴的全排列演算法

以abcd為例:

對於abcd,首先以第一位的字元分為四類:

(1)以a為第一位 abcd  固定a的位置,a後面跟著bcd的全排列

(2)以b為第一位 bacd (即交換第乙個字元a和b的位置),固定b的位置,b後面跟著acd的全排列

(3)以c為第一位 cbad (即交換第乙個字元a和c的位置),固定c的位置,c後面跟著bad的全排列

(4)以d為第一位 dbca (即交換第乙個字元a和d的位置),固定d的位置,d後面跟著bca的全排列 

同樣的,對於(1)中bcd、(2)中的acd、(3)中的bad、(4)中的的bca的全排列,分別按照上面的形式遞迴求解。

**如下:

#include using namespace std;

templatevoid permutation(t array, int start, int end)

(右邊的數從右至左是遞增的,因此k是所有大於pj的數字中序號最大者)

3)對換pj,pk

4)再將pj+1......pk-1pkpk+1......pn倒轉得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,這就是排列p的下乙個排列。

舉個栗子:

1)從右端數字1開始,找到第乙個比相鄰的右邊小的數字,這個數字為3,記下3在數列中的位置 j=1(最左邊從0開始數)

2)找出3右邊的數字中,第乙個比3大的數字,這個數為4,記下這個數的位置 k=3

3)交換位置 j 的數字(3)和位置k 的數字(4),數列變為24531

4)反轉位置 j後面的數列(531),最終數列變為24135

24135即為原數列23541的下乙個字典序排列。

注意,如果原始序列為54321,已經為最大排列,那麼按照上面的方法,是找不到下乙個字典序的排列的。

所以,首先要對原始序列進行預處理,有兩種方法:

方法1,利用快速排序將原始序列按公升序排序,這樣就得到最小的排列pmin

方法2,判斷原始序列是不是最大排列pmax,若是,反轉pmax,使其成為pmin

實現**:

//交換陣列s中下標為x和y的兩個元素值

swap(char *s,int x, int y)

//反轉序列

reverse(char *s,int x, int y)

s[start]=s[end];

while(start=s[start]中的等號是為了避免序列中有重複的字元而導致的重複的排列

while(start>0&&s[start-1]>=s[start])

if(start==0)

return false;

while(end>start-1&&s[start-1]>=s[end])

swap(s,start-1,end);

reverse(s,start,len-1);

return true;

}void permutation(char *s,int len){

//快速排序,使原序列為最小乙個排列pmin

qsort(s,0,len-1);

/*//也可以不使用qsort對原序列進行排序,首先判斷原序列是否是最大的排列pmax,如果是的話,反轉原序列

int boolvalue=0;

for(int i=0;i

如果不想自己寫全排列的**的話,可以直接使用c++的stl中的函式next_permutation. 它的作用是判斷乙個序列,若存在下乙個字典序排列,那麼就返回true並產生這個排列,否則返回false。

#include #include using namespace std;

template void permutation(bidirectionaliterator array, int len)

{ sort(array, array + len);

do{

for(int i = 0; i < len; ++i){

cout<

參考文章:

全排列演算法 遞迴 字典序實現(Java)

全排列 從n個不同元素中任取m m n 個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。當m n時所有的排列情況叫全排列。例如 1 2 3三個元素的全排列為 解法1 遞迴 如下圖 要對1 2 3 4進行排序,第乙個位置上的元素有四種可能 1或2或3或4,假如已經確定了第乙...

全排列 方法 全排列函式和遞迴和字典序

給你乙個字串,按字典序從小到大輸出這個字串的全排列 乙個由小寫字母組成的長度小於等於8的不含重複字元的字串 按字典序從小到大輸出這個字串的全排列 abcabc acbbac bcacab cbanext permutation函式 組合數學中經常用到排列,這裡介紹乙個計算序列全排列的函式 next ...

全排列演算法的字典序排列

之前在中描述了全排列演算法的遞迴解法,這裡再說一種演算法 字典序排列。字典序排列就是按照字典a z,1 9的順序給出字串的順序全排列,例如abc的全排列就是從abc一直排到cba。那麼給定乙個字串,怎麼找出恰好大於該字串的下乙個排列呢?我們考慮如下的步驟 1 假設字串為p1p2 pn,我們從後往前尋...