稍微改进了一下,如果不输出的话n<=10的时候都在1.2秒一下完成,对于递归来说还是慢了。
0 1
1 0
0 1 2
1 0 2
1 2 0
2 0 1
2 1 0
#include<iostream>
#include<stdio.h>
using namespace std;
#define OK 1
#define ERROR 0
#define Status int
class Permutation{
protected:
int **b;
int size;
int sum;
void permu(int length)
{
int sum1;
sum1=1;
int i;
for(i=1;i<=length;i++)
{
sum1*=i;
}
sum=sum1;
}
public:
Permutation()
{
size=0;
}
~Permutation(){}
/**
* 对1 -length进行一个排序
*/
void setb(int length)
{
permu(length);
size=length;
if(length<=0){
return;
}
else if(length==1){
b=new int*[1];
b[0]=new int[1];
b[0][0]=1;
return;
}
int i,j,pre,s=2,times,times1,k,value;
b=new int*[sum]; //动态建立 length! 行的二维矩阵
for(i=0;i<sum;i++)
{
b[i]=new int[length]; //每一行长度为 length
}
/**
* 起始二维矩阵是 1 2
* 2 1
*/
b[0][0]=1;b[0][1]=2;b[1][0]=2;b[1][1]=1;
/**
* times ← 0 to length-2
* 由于1 和 2 已经放上去了,所以只需要再放length-2个数字即可
*/
for(times=0;times<length-2;times++)
{
pre=s;//pre=2→
permu(++s);//permu(3→)
value=sum/s;
for(i=0;i<value;i++)// s-1 的排列组合结果后面加下一个数字
{
/**
* 1 2 3
* 2 1 3
*/
b[i][s-1]=s;
}
times1=0;
/**
* 只需要处理一半数据,剩余的一半用栈逆序输出
* 上面的for循环在上一次的结果后面添加了下一个数字以后,开始增加剩余的排列
* m/s = (s-1)! = 上次获得的所有结果数
*/
for(;i<sum/2;i++)
{
if(times1%value==0)//如果完成了一组交换,每一组数量为m/s个,则
{
pre--;//pre指针向前挪一位,做下一对的交换
}
for(k=0;k<pre;k++)
{
b[i][k]=b[i-value][k];//把上一组对应行的结果复制到这一行来
}
b[i][k]=b[i-value][k+1];
b[i][++k]=b[i-value][k-1];
for(k++;k<s;k++){
b[i][k]=b[i-value][k];//把上一组对应行的结果复制到这一行来
}
times1++;//交换次数+1
}
/*
* 完成这一次一半的工作量后,开始用逆序输出完成下一半的工作量
*/
for(j=sum/2-1;j>=0,i<sum;j--,i++)
{
for(k=0;k<s;k++){
b[i][s-k-1]=b[j][k];
}
}
}
}
void display()
{
int i,j,k=0;
for(i=0;i<sum;i++)
{
for(j=0;j<size-1;j++)
{
printf("%d ",b[i][j]);
}printf("%d\n",b[i][j]);
}
}
};
int main()
{
int n=10;
Permutation p;
p.setb(n);
p.display();
return 0;
}