全排列算法

从1到N,输出全排列,共N!条。
分析:用N进制的方法吧。设一个N个单元的数组,对第一个单元做加一操作,满N进
一。每加一次一就判断一下各位数组单元有无重复,有则再转回去做加一操作,没
有则说明得到了一个排列方案。[@more@]


解法一:执行速度:10秒
#include
#define n 5
int a[n],b[n];
void swap(int m)
{
int b1=b[m];
int b0=b1;
while(a[b0]>=m){
b0--;
if(b0<0)b0=n-1;
}
int temp=a[b0];
a[b0]=a[b1];
a[b1]=temp;
int a0=a[b0];
int a1=a[b1];
temp=b[a0];
b[a0]=b[a1];
b[a1]=temp;
}
void output()
{
for(int j=0;j printf("%d ",a[j]);
}
printf("n");
}
void permute(int m)
{
m--;
for(int i=m;i>=0;i--){
permute(m);
if(i>0){
swap(m);
output();
}
}
}
void main()
{
for(int i=0;i a[i]=b[i]=i;
}
output();
permute(n);
}

解法二:5秒
# include
# include
int N;
main()
{
int i,j,k,m,n,*l,*a,m2;
scanf("%d",&N);
if(N<3)
{
puts("N太小!");
exit(1);
}
/* 开数组 */
l=malloc(N*sizeof(int));
a=malloc(N*sizeof(int));
/* 赋初值 */
for(i=0;i {
a[i]=0;l[i]=i+1; /* a[i]-1是第i个元素交换的次数 */
}
m=2;put(l);
do
{
n=l[1];l[1]=l[0];l[0]=n;put(l); /* 头两个先换一下 */
/* 判断该换哪个了 */
while(a[m-2] == m)
m++;
if(m==N) break;
/* 下面是整理过程,可能还有办法 */
n=m>>1;
for(i=0,j=m-1;i {
k=l[i];
l[i]=l[j];
l[j]=k;
} /* 以上是从小到大重排,下面处理好了可能不必做,因为可以无序
*/
m2=m-2;
a[m2]++;
/* 下面该把第j个和第m个交换 */
j=m-a[m2];
n=l[j];l[j]=l[m];l[m]=n;
put(l);
/* m以前的重排 */
for(i=0;i a[i]=0;
m=2;
} while(1);
}
put(int *l)
{
int i;
for(i=0;i printf(" %2d",l[i]);
putchar('n');
}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/82394/viewspace-905987/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/82394/viewspace-905987/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值