// 全排列的非递归实现。当作是一个数字,从低到高。
#include <stdio.h>
#include <assert.h>
#include <algorithm>
using namespace std;
void swap_(int &a, int &b);
void print(int *p, int n);
void perm(int*a, int nn, int *p, int n);
void perm2_(int *a, int n);
int main()
{
int a[8]={1,1,3,4,5,6,7,8};
perm(a,3,a,3);
printf("\n");
sort(a,a+4);
perm2_(a,3);
//perm(a,4,a,4);
return 0;
}
void perm2_(int *a, int n)
{
while(true)
{
print(a,n);
int i,m1,m2,j;
for (i=n-2; i>=0; i--)
{
if (a[i] < a[i+1])
{
m1=i;
break;
}
}//
if (i < 0)
{
break;
}
for (i=n-1; i>m1; i--)
{
if (a[i] > a[m1])
{
m2=i;
break;
}
}//
swap_(a[m1], a[m2]);
for (i=m1+1, j=n-1; i<j; i++,j--)
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
void print(int *p, int n)
{
int i;
for (i=0; i<n; i++)
{
printf("%d ", p[i]);
}
printf("\n");
}
void swap_(int &a, int &b)
{
if (a==b)
{
return;
}
a^=b;
b^=a;
a^=b;
}
void perm(int*a, int nn, int *p, int n)
{
if (n==1)
{
print(a,nn);
return;
}
int i;
for (i=0; i<n; i++)
{
swap_(p[0],p[i]);
perm(a, nn, p+1, n-1);
swap_(p[0],p[i]);
}
}
缺点:需要移动和反转,因此每次移动了多个元素。
优点:可以处理重复元素。