这是第一次写算法的博客!~~不足的地方请各位高手纠正。。。。。。
算法的精髓在于想,然后再用想法找到规律成为伪代码,最后将伪代码翻译成真代码!(其实最后一个过程本人觉得有点难),不废话啦!进主题。。。。
全排列是可以用递归的思想来解决的。
1、解释一下全排列是什么?其实全排列是高中的排列组合模型,我们可以很清楚的解决个数问题,当有n个数字时它的个数为
n!个不同的排列。例如:{1,2,3,4}这4个数字有4!个不同的排列,也就是24种。
2、解决递归算法的出发点是必须找到一个临界点(自己已经知道这个值)例如:全排列中当只有一个数全排列是,他肯定是1.
3、找到这个临界点后,然后就找通式。设R={r1,r2,r3,....,rn}是要进行排列的n个元素,集合X中元素的全排列记为Perm(X)。
Ri=R-{ri},(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。分析过程如下:
现以{1, 2, 3, 4, 5}为例说明如何编写全排列的递归算法。
3.1、首先看最后两个数4, 5。 它们的全排列为4 5和5 4, 即以4开头的5的全排列和以5开头的4的全排列。
由于一个数的全排列就是其本身,从而得到以上结果。
3.2、再看后三个数3, 4, 5。它们的全排列为3 4 5、3 5 4、 4 3 5、 4 5 3、 5 3 4、 5 4 3 六组数。
即以3开头的和4,5的全排列的组合、以4开头的和3,5的全排列的组合和以5开头的和3,4的全排列的组合.
4、总结:
当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;
当n>1时,Perm(R)由(r1)Perm(R1)+(r2)Perm(R2)+....+(rn)Perm(Rn)构成。
5、代码(用C++写的)
#include<iostream>
using namespace std;
void Swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
void Perm(int list[],int k,int m)//k为数组中开始排列的位置,m为数组中结束排列的位置
{
if(k==m)
{
for(int i=0;i<=m;i++)
cout<<list[i]<<"\t";
cout<<endl;
}
else
{
for(int i=k;i<=m;i++)
{
Swap(list[k],list[i]);//将前缀放在当前开始排列的位置
Perm(list,k+1,m);//去掉前缀的全排列
Swap(list[k],list[i]);//将当前前缀放回原来数组中的位置
}
}
}
int main()
{
int list[4]={1,5,9,4};
Perm(list,0,3);
return 0;
}
注释:代码的注释很重要要理解!