前面我們介紹了全排列的非遞迴演算法,現在我再來寫一下全排列的遞迴演算法:
這兩種演算法的演算法思路並不相同。遞迴演算法的思路比較接近於我們現實生活中的思路。
1.試想,我們只有兩個數字:12.要對它進行全排列,第一種方式就是12本身,第二種,將12交換,變為21即可。這提示了我們一種交換的思路。
2.但這概括的並不全面。試想,我們要對123進行全排列。我們可以採用將1固定,「23」進行全排列,將「2」固定,對「13」進行全排列。將「3」固定,對「12」進行全排列。
這其實就是首部為」1「,然後是「2」,然後是「3」,不就是第二位後邊的數依次和第一位進行交換麼?這是典型的遞迴的思路。
3.但是,這樣也不全面,我們每次交換要將排列恢復成為原始的「123」,因為這個演算法求排列的時候,前後並沒有依賴性,其參考物只有「123」這個原始的第乙個排列。否則,如果我們不恢復的話,就會出現,雖然數量與正確解法相同,但是會有重複的排列的現象。
這樣,我們不難寫出**:
[cpp]view plain
copy
#include
using namespace std;
int total = 0;
//交換函式
void swaparray(int &a,int &b)
//遞迴函式
void fullpermutation(int * fullarray,int start,int end,int number)
cout} else
} }
int main()
fullpermutation(fullarray,0,number-1,number);
cout<<"total = "}
全排列在很多程式都有應用,是乙個很常見的演算法,常規的演算法是一種遞迴的演算法,這種演算法的得到基於以下的分析思路。 給定乙個具有n個元素的集合(n>=1),要求輸出這個集合中元素的所有可能的排列。
一、遞迴實現
例如,如果集合是,那麼這個集合中元素的所有排列是,顯然,給定n個元素共有n!種不同的排列,如果給定集合是,可以用下面給出的簡單演算法產生其所有排列,即集合(a,b,c,d)的所有排列有下面的排列組成:
(1)以a開頭後面跟著(b,c,d)的排列
(2)以b開頭後面跟著(a,c,d)的排列
(3)以c開頭後面跟著(a,b,d)的排列
(4)以d開頭後面跟著(a,b,c)的排列,這顯然是一種遞迴的思路,於是我們得到了以下的實現:
[cpp]view plain
copy
#include "iostream"
using namespace std;
void permutation(char* a,int k,int m)
else
} } int main(void)
二、stl實現
有時候遞迴的效率使得我們不得不考慮除此之外的其他實現,很多把遞迴演算法轉換到非遞迴形式的演算法是比較難的,這個時候我們不要忘記了標準模板庫已經實現的那些演算法,這讓我們非常輕鬆。stl有乙個函式next_permutation(),它的作用是如果對於乙個序列,存在按照字典排序後這個排列的下乙個排列,那麼就返回true且產生這個排列,否則返回false。注意,為了產生全排列,這個序列要是有序的,也就是說要呼叫一次sort。實現很簡單,我們看一下**:
[cpp]view plain
copy
#include "iostream"
#include "algorithm"
using namespace std;
void permutation(char* str,int length)
while(next_permutation(str,str+length));
} int main(void)
三、有一定約束條件的全排列
對數1,2,3,4,5要實現全排序。要求4必須在3的左邊,其它的數字置隨意。
思路:首先使用上面的2種方法之一實現全排列,然後對全排列進行篩選,篩選出4在3左邊的排列。
[cpp]view plain
copy
#include "iostream"
#include "algorithm"
using namespace std;
void permutation(int* a,int length)
if(flag==1) //如果4在3的左邊,執行完**,flag就是1
}while(next_permutation(a,a+length));
} int main(void)
**)
遞迴實現全排列
生成全排列的最簡單的遞迴方法的思想 1.可以把幾個數字分成前半部和最後一位。對於0123這四個數來說,最後一位 紅色字型 所出現的情況只有以下四類 先不管前三個數的排列組合情況 3 2 1 0這樣我們就把四個數字的排列問題,變成了3個 對於上述的每一行來說 2.終結條件是1個數字的排列就是其本身。直...
遞迴實現全排列
1 如果運算力,和理亂麻的水平不夠。盡量不要復用本地變數 比如c用來計數,不計數後 又用來做其它比如作為步長 除非你確認不會出現問題。2 盡量讓每個邏輯單元 函式內可以有多個邏輯單元 盡量小,邏輯盡量要清晰 3 語言組織能力有限,就說這些了。未整理,抱歉了 include stdafx.h incl...
全排列遞迴實現
一 遞迴版本 1 演算法簡述 簡單地說 就是第乙個數分別以後面的數進行交換 e g e a b c 則 prem e a.perm b,c b.perm a,c c.perm a,b 然後a.perm b,c ab.perm c ac.perm b abc acb.依次遞迴進 好了,知道演算法之後就...