C 語言實現 演算法分析與設計 全排列問題

2021-10-23 00:04:48 字數 2817 閱讀 1847

設a=是要進行排列的n個元素的集合

這裡用技巧性演算法,即觀察

當n=1時,輸出a1

當n=2時,輸出a1a2,a2a1

當n=3時,輸出:

我們注意觀察,每種可能的排列的第乙個元素,我們發現第乙個元素的值只能是n=3時,出現的所有可能的元素,而後面則是另外剩下的3-1=2個數的全排列,而這另外剩下的3-1=2個數的全排列恰好就是n=2時的操作步驟,也就是說,先確定首元素,其餘元素執行上一步的全排列,這樣不斷地執行上一步的上一步……就達到了遞迴的效果,即有了這樣乙個函式:

range(a) = a1range(a1), a2range(a2),…, anrange(an)

這個演算法的c++實現如下(by 漫天風沙裡的人):

#include

using

namespace std;

//例:遞迴與排列問題

void

printresult

(char a,

int n)

//用於列印排列結果的函式

cout<

}void

range

(char a,

int k,

int n)

//a字元數字代表要排序的序列

//k是從**開始排列,n是陣列有多少個元素

//這裡k和n減去1是為了讓這個陣列貼合題目要求下標從1開始

else}}

intmain()

;range

(a,1,4

);return0;

}

【注意】有關迴圈中兩次交換和一次遞迴呼叫函式的解釋:

(我們假設排序這個字元陣列char a = ,對其進行全排列)首先判斷,第一次交換其實並不是真正的交換,我們可以看到

//第二種類開始才正式有交換效果

temp = a[k-1]

; a[k-1]

= a[i]

; a[i]

= temp;

這裡僅僅是為了選擇首元素進行全排列,讓a[k]和a[i]的值進行交換,這句話的通俗解釋如下:

比如有四個字母abcd進行全排列,那麼根據剛才的演算法,我們應該選擇首元素,然後讓首元素後面的元素進行全排列,那麼接下來進行第一次交換,第一次交換時,我們知道k=1(k-1=0,這裡為了讓大家能通俗的理解,c++陣列下標預設從0開始,我取k-1後就可以理解為從1開始了),a[k]目前是』a』,很湊巧a[i]也是』a』,這就確定了首元素是a,然後確定首元素後就知道首元素後面的其他元素都是什麼,對後面的元素進行全排列,即目前:

執行後三個問號是bcd進行全排列,那麼bcd全排列還需要確定其首元素,接下來就執行遞迴操作:

range

(a,k+

1,n)

;//遞迴呼叫排列剩下兩個元素

遞迴時先判斷一下k和n的值,我們知道,k已經在執行語句時增加了1即現在k是2,而n還是4,這個時候進入遞迴,我們再執行一遍剛才的交換,此時a[k]是』b』,a[i]是』b』,這就進入到了b為首元素的,剩下兩個元素的全排列,即:

然後又進入遞迴:

range

(a,k+

1,n)

;//遞迴呼叫排列剩下兩個元素

執行後k變成了3,n還是4,繼續,不符合if的條件,繼續進入迴圈,此時a[k]是』c』,a[i]是』c』,此時就進入到了c為首元素,剩下乙個元素的全排列,乙個元素只有一種排法,當然現在我們只看說c首元素,即:

range

(a,k+

1,n)

;//遞迴呼叫排列剩下兩個元素

執行後k=4,n=4,符合了if條件,開始列印,即列印了四個元素全排列的第乙個結果:

然後列印後,沒了if條件沒了其他**,則應該是退出range函式,我們需要注意此時已經執行了三層的遞迴函式range,這三層分別是:

【注意:為什麼沒有k=4,n=4呢,因為那個時候符合了if條件,而if條件中並沒有執行遞迴的**,而是列印並結束函式】

則退回倒數第二層的遞迴時,退回到上一層k=3,n=4的時候,然後接下來繼續執行for迴圈的下一半即

這個時候做了個交換,這個交換的意思是,首元素由k=3,n=4時的c換成了d,即此時變成了如下情況:

然後注意,我們現在在else條件的迴圈體裡,這時執行完了倒數第二層的else條件的迴圈體中的第一層迴圈,我們知道此時迴圈是從k到n的即3到4的,剛執行的第一次是k=3,接下來執行第二次i=4時(注意只是i增加,k並沒有增加還是3)的迴圈,由於此時k=3,a[k]是』c』(再次提醒我們這裡的陣列是下標從1開始),i也是4,a[i]是』d』,這次做了一次真正的交換,a[k]變成了』d』,a[i]變成了』c』,即原字元陣列a=,然後執行了到了下一步遞迴:

range(a,k+1,n);//遞迴呼叫排列剩下兩個元素

執行後k=4,n=4,符合if條件,開始列印,得到了四個元素全排列的第二個結果即:

接下來無限地重複上述過程……那麼總結起來大概是這樣的步驟圖(博主字太爛,見諒)【注意:k-1等於n-1相當於k等於n,這麼寫是為了時刻提醒大家這裡是以下標1開頭的陣列做說明】:

C語言實現全排列演算法

題目 輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c 所能排列出來的所有字串 abc acb bac bca cab 和cba。includeusing namespace std void permutation char pstr,char pbegin ...

全排列的演算法與C語言實現

全排列是將一組數按一定順序進行排列,如果這組數有n個,那麼全排列數為n 個。現以為 例說明如何編寫全排列的遞迴演算法。1 首先看最後兩個數4,5。它們的全排列為4 5和5 4,即以4開頭的5的全排列和以5開頭的4的全排列。由於乙個數的全排列就是其本身,從而得到以上結果。2 再看後三個數3,4,5。它...

全排列的演算法與C語言實現

全排列是將一組數按一定順序進行排列,如果這組數有n個,那麼全排列數為n 個。現以為 例說明如何編寫全排列的遞迴演算法。1 首先看最後兩個數4,5。它們的全排列為4 5和5 4,即以4開頭的5的全排列和以5開頭的4的全排列。由於乙個數的全排列就是其本身,從而得到以上結果。2 再看後三個數3,4,5。它...