/*
字典排序算法:排列按照增序排队,比如:123 132 213 231 312 321
算法:从右到左扫描一个当前的排列,寻找第一对连续的元素ai和ai+1,
并且ai<ai+1(同时,ai+1>ai+2>...>an).然后在尾部寻找大于ai的最小
数字并将它放在位置i上.从i+1到n的位置以元素ai,ai+1,...,an的增序
进行填充.
*/
#include<stdio.h>
#define NR 20
void HeapAdjust(int a[],int s,int m) /*堆排序算法*/
{
int rc,j;
rc=a[s];
for(j=2*s+1;j<=m;j*=2)
{
if(j<m && a[j]<a[j+1])
++j;
if(rc>=a[j])
break;
a[s]=a[j];
s=j;
}
a[s]=rc;
}
int findi(int a[],int n) /*从右到左扫描一个当前的排列,寻找第一对连续的元素ai和ai+1,*/
{ /*并且ai<ai+1(同时,ai+1>ai+2>...>an),然后返回ai所在的下标i.*/
int i,j,flag=0; /*如果找不到,则返回-1*/
for(i=n-2;i>=0;i--)
{
if(a[i]<a[i+1])
{
if(i==n-2)
{
break;
}
for(j=i+2;j<n;j++) /*判断ai+1是否大于后面的所有元素*/
{
if(a[i+1]<a[j])
{
flag=0;
break;
}
flag=1;
}
}
if(flag) /*找到了,退出循环*/
{
break;
}
}
return i;
}
int main()
{
int i,j,n,k,a[NR],b[NR],temp;
printf("Please enter a number:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
a[i]=i+1;
printf("%d ",i+1);
}
printf("/n");
j=findi(a,n);
while(j!=-1) /*如果找不到满足aj<aj+1且aj+1>..>an,则宣告排序全部完成*/
{
for(i=0;i<n-j;i++) /*把aj和它后面的所有元素拷贝到b数组中*/
b[i]=a[i+j];
for(i=(n-j)/2-1;i>=0;--i)
HeapAdjust(b,i,n-j-1);
for(i=n-j-1;i>0;--i)
{
temp=b[0];
b[0]=b[i];
b[i]=temp;
HeapAdjust(b,0,i-1);
} /*对b数组进行堆排序*/
for(i=0;i<n;i++)
{
if(b[i]>a[j])
{
k=i;
break; /*找出aj+1到an中大于aj的最小数字*/
}
}
a[j]=b[k]; /*把它放在位置j上*/
for(i=0;i<k;i++)
a[j+1+i]=b[i];
for(i=k+1;i<n-j;i++) /*从j+1到n的位置以元素aj,aj+1,...an的增序进行填充*/
a[j+i]=b[i];
for(i=0;i<n;i++)
printf("%d ",a[i]); /*输出当前的排序*/
printf("/n");
j=findi(a,n);
}
return 0;
}
或:
#include <iostream>
#include <algorithm>
#include <iterator>
#define N 4
int main()
{
using namespace std;
int a[N] = { 1, 2, 3 ,4};
do
{
copy( a, a+N, ostream_iterator<int>(cout," ") );
cout << endl;
} while( next_permutation(a,a+N) );
return 0;
}