产生全排列的算法问题看似简单,实际也是一个经典的问题。以下给出了两种解法,一种是递归解法,另一种是STL模板库里面的产生下一个排列数的函数源代码。
方法一: 将产生N个数的全排列的问题看成先产生一个数的排列,再产生两个数的排列,当N=n时,递归出口,输出所求的排列。整个过程形成一颗递归树。
level为树的深度,最深为n,输出结果。每输出一个结果需要一个向量保存中间的排列。
0
10 01
210 120 102 201 021 012
#include <iostream>
#include <vector>
using namespace std;
void gen(vector<int> & permutation, int level, int n)
{
int i;
if(level==n)
{
for(i=0;i<n;i++)
cout<<permutation[i];
cout<<endl;
}
else
{
for(i=0;i<=level;i++)
{
vector<int> p(permutation);
p.insert(p.begin()+i,level);
gen(p,level+1,n);
}
}
}
int main()
{
int n;
cin>>n;
vector<int> permutation;
gen(permutation,0,n);
return 0;
}
方法二:使用STL里面的next_pemutation算法
该算法的思想是:
1234-》4321
排列按字典序生成结果。
每次根据给出的排列(First,...,Last),先找寻一个顺序对n,n1,然后将该顺序对左面的数n,与从右开始看,比该数小的那个数m交换;将n1与Last之间的数逆序。
// next_permutation and prev_permutation, with and without an explicitly
// supplied comparison function.
/**
* @brief Permute range into the next "dictionary" ordering.
* @param first Start of range.
* @param last End of range.
* @return False if wrapped to first permutation, true otherwise.
*
* Treats all permutations of the range as a set of "dictionary" sorted
* sequences. Permutes the current sequence into the next one of this set.
* Returns true if there are more sequences to generate. If the sequence
* is the largest of the set, the smallest is generated and false returned.
*/
template<typename _BidirectionalIterator>
bool
next_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last)
{
if (__first == __last)
return false;
_BidirectionalIterator __i = __first;
++__i;
if (__i == __last)
return false;
__i = __last;
--__i;
for(;;)
{
_BidirectionalIterator __ii = __i;
--__i;
if (*__i < *__ii)
{
_BidirectionalIterator __j = __last;
while (!(*__i < *--__j))
{}
std::iter_swap(__i, __j);
std::reverse(__ii, __last);
return true;
}
if (__i == __first)
{
std::reverse(__first, __last);
return false;
}
}
}