以前看过一些全排序算法,大致思路如下:
在数组中,轮流选一个元素作为头字符,然后剩下的数组元素在做全排序。这是一个典型的递归算法。
还有一个方法就是使用next_permutation这个标准库函数,这个函数的作用是一个范围的值变成字典序中的下一个值,即按字典序排的话,新的字符串(或数组)刚好是以前那个的下一位,原函数如下:
template inline
bool next_permutation(_BidIt _First, _BidIt _Last)
{ // permute and test for pure ascending, using operator<
_BidIt _Next = _Last;
if (_First == _Last || _First == --_Next)
return (false);
for (; ; )
{ // find rightmost element smaller than successor
_BidIt _Next1 = _Next;
if (*--_Next < *_Next1)
{ // swap with rightmost element that's smaller, flip suffix
_BidIt _Mid = _Last;
for (; !(*_Next < *--_Mid); )
;
std::iter_swap(_Next, _Mid);
std::reverse(_Next1, _Last);
return (true);
}
if (_Next == _First)
{ // pure descending, flip all
std::reverse(_First, _Last);
return (false);
}
}
}
分析next_permutation函数执行过程:
假设数列 d1,d2,d3,d4……
范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照字典序。例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确定这个下一排列为字典序中的next,而不是next->next->next……
若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最小字典序。
返回为true表示生成下一排列成功。下面着重分析此过程:
根据标记从后往前比较相邻两数据,若前者小于(默认为小于)后者,标志前者为X1(位置PX)表示将被替换,再次重后往前搜索第一个不小于X1的数据,标记为X2。交换X1,X2,然后把[PX+1,last)标记范围置逆。完成。
要点:为什么这样就可以保证得到的为最小递增。
从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。[PX+1,last)总是递减的,[first,PX)没有改变,因为X2>X1,所以不管X2后面怎样排列都比原数列大,反转[PX+1,last)使此子数列(递增)为最小。从而保证的新数列为原数列的字典序排列next。
本段来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/aipb2008/archive/2008/03/29/2227490.aspx.
然后我仿着这个写了个类似的函数,仅仅用于对整形数组进行字典序排序
#include<iostream>
#include<algorithm>
using namespace std;
bool next_per(int a[],int n);
int main()
{
int a[4] = {2,3,1,4};
sort(a,a+4);
do{
for(int i = 0; i < 4; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}while(next_per(a,4));
system("pause");
return 0;
}
void swap_int(int a[], int x, int y)
{
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
void reverse(int a[], int start , int end)
{
if(start < end)
{
swap_int(a,start,end);
}
}
bool next_per(int a[],int n)
{
if(n == 1 || n == 0)
return false;
int m = n - 1;
int next = a[n-1];
for(;;)
{
int next1 = a[m];
if(a[--m] < next1)
{
int m1 = m;
int end = n;
for(;!(a[m1] < a[--end]););
swap_int(a,m1,end);
reverse(a,m + 1,n-1);
return true;
}
if(m <= 0)
{
return false;
}
}
}
这是整个文件了。