排列问题:
设R={r1,r2,r3,……,rn}要进行排列的n个元素,Ri=R-{ri}。集合X中的元素的全排列记为Perm(X)。R的全排列可归纳为如下:
当n=1时,Perm(R)=(r),其中r时集合R中的唯一一个元素;
当n>1时,Perm(R)由(rn)Perm(Rn)构成。
一次递归定义,可设计产生Perm(R)的递归算法如下:
template<class Type>
void Perm(Type list[], int k, int m )
{ //产生[list[k:m]的所有排列
if(k==m)
{ //只剩下一个元素
for (int i=0;i<=m;i++)
cout<<list[i];
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]);
}
}
template<class Type>
inhne void Swap(Type &a,Type @b){
Type temp=a;a=b;b=temp;
}
写到这大家可能多这算法有了一定的了解,这篇文章不进行代码实现,目的就是用实例为大家讲解一下整个过程,让大家在明白原理的同时,能更好的吸收这个问题。
下面以list[3,4,5],k=0,m=2为例子,请抽出三分钟仔细跟着下图走一遍,讲解如下:
大家可以看到,在for循环中,每次的第一次交换是为了将没有在当前位置出现过的数字交换到当前位置;第二次交换是为了保证数据的原始性,在输出数据之后,将每次交换的结果恢复成交换前的模样。
但是递归是把双刃剑,在使用递归时必须设置递归的终止条件,否则还是不要轻易使用递归。