首先,給出算法的思路
設R={r1,r2,...,rn}是要進行排列的n個元素,Ri=R-{ri}。
集合X中元素的全排列記為permutation(X),(ri)permutation(X)表示在全排列permutation(X)的每一個排列前加上前綴ri得到的排列。
R的全排列可歸納定義如下:
當n=1時,permutation(R)={r},r是集合R中唯一的元素;
當n>1時,permutation(R)由(r1)permutation(R1),(r2)permutation(R2),……,(rn)permutation(Rn)構成。
此算法要求待排列的數據是互異的,因為該算法不能檢測同種排列是否已經輸出,如:
1, 1, 2
那么,全排列期望輸出是:
1, 1, 2
1, 2, 1
2, 1, 1
但是該算法的輸出:
1, 1, 2
1, 2, 1
2, 1, 1
1, 1, 2
1, 2, 1
2, 1, 1
這是該算法的缺點,也限制了它的適用范圍。
程序描述如下:
#include?
<
iostream
>
#include?
<
algorithm
>
?
using
?
namespace
?std;?
//
?遞歸產生R[k:n]的所有的排列,元素是互異的
template?
<
class
?Type
>
void
?permutation(Type?
*
R,
int
?k,
int
?n)
{
????
if
(k
==
n)
????{
????????
for
(
int
?i
=
0
;i
<
n;
++
i)
????????????cout?
<<
?R[i]?
<<
?
"
\t
"
;
????????cout?
<<
?endl;
????}
????
else
????????
for
(
int
?i
=
k;i
<
n;
++
i)
????????{
????????????swap(R[k],R[i]);
????????????permutation(R,k
+
1
,n);
????????????swap(R[k],R[i]);
????????}
}
還有一種很簡單的方法,使用GP中的方法
該算法是STL中的范型算法,當然效果是很好的,不會出現上面的算法的情況。
程序描述如下:
//
?使用泛型算法next_permutation()
#include?
<
iostream
>
#include?
<
vector
>
#include?
<
algorithm
>
?
using
?
namespace
?std;?
//
?產生R[k:n]的所有的排列
template?
<
class
?Type
>
?
void
?pernutation(Type?
*
R,
int
?k,
int
?n)
{
?vector
<
Type
>
?myVec;
?
int
?i,size?
=
?n?
-
?k;
?
for
(i?
=
?k;i?
<
?n;i
++
)
??myVec.push_back(R[i]);
?
//
?使用next_permutation()函數必須是有序的數據
?sort(myVec.begin(),myVec.end());
??
?
do
?{
??
for
(i?
=
?
0
;i?
<
?size;i
++
)
???cout?
<<
?myVec[i]?
<<
?
"
\t
"
;
??cout?
<<
?endl;
?}
?
while
(next_permutation(myVec.begin(),myVec.end()));
}
注:這里的待全排的數據是存在數組或者向量中的。