全排列算法

来源:互联网 发布:拍电影的软件 编辑:程序博客网 时间:2024/04/30 03:50

这是第一次写算法的博客!~~不足的地方请各位高手纠正。。。。。。

算法的精髓在于想,然后再用想法找到规律成为伪代码,最后将伪代码翻译成真代码!(其实最后一个过程本人觉得有点难),不废话啦!进主题。。。。

全排列是可以用递归的思想来解决的。

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;}
注释:代码的注释很重要要理解!