1 Star 0 Fork 0

liyinxin / Algorithm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
递归 4.09 KB
一键复制 编辑 原始数据 按行查看 历史
全排列算法:递归实现
template<typename T> void recursive::permutations(T list[],int k,int m)const{
if(k==m){
std::copy(list,list+m+1,std::ostreambuf_iterator<T>(std::cout));
std::cout<<std::endl;
}
else{
for(int i = k;i <= m;++i){
std::swap(list[k],list[i]);//这个是把一个元素,拿出来,然后,剩下的组成一个集合
permutations(list,k+1,m);//剩下的数据组成的集合
std::swap(list[k],list[i]);//处理完第一个位置的元素以后,再换回来,恢复原样
}
}
}
/*
算法思想:全排列的算法可以写成如下形式:
{ 1; n= 1
f(n) = {
{ Eif(n-1); n>=2
这个表达式的意思指的是:如果一个集合E={e1,e2,e3,e4,...,en};那么可以按照下面的递归方式去产生一个全排列:
(1)先在n个元素中随便拿出一个元素ei(i属于1,...n)。然后剩下的元素组成E(n-1)。
(2)剩下的这些元素继续执行这个递归方法,直到n=1的时候,返回该元素(因为一个元素的组合就是它本身了)
那么第一个条件可以这样描述,因为要随便从n个元素中取一个元素。所以可以使用一个for循环来取元素也就是:
for(int i = k; k <= m;++i)//这里的k,m都是一个数组的下标,所以表达的长度就是m-k+1了,也就是获取
m-k+1个元素了。因为每一个f(n)都是通过f(n-1)得来的。所以这个时候,可以让k增加(也就是在每一次递归的时候k都要增加一。
解决了n个元素的范围,那么接下来就得取出这些个元素。我们可以使用std::swap()函数去让数组的第一个元素跟别的元素交换。
这样就可以把第一个元素取出来,然后让剩下的元素组成下一个元素集合了。
swap(list[k],list[i]) //让每一个集合的第一个位置与其他的位置元素的集合进行交互位置。
取出一个元素后,那么我们就得去递归了也就是ei*f(n-1)了。所以接下来就是调用自身(也就是递归)。不过这个时候要注意传给它自己
的参数:
permutations(list,k+1,m); //这个时候,下一个自身的调用的k变大了,也就是上面说的,比以前大一。
然后m是不变的,(m可以理解为尾部,尾部是不可以变的,要让尾部变化,去接近尾部)。
然后就这样递归。直到到达只有一个元素的集合。然后开始回溯。
std::swap(list[k],list[i]);//处理完第一个位置的元素以后,再换回来,恢复原样
注意这个语句。这个也是很必要的!那么这句话的作用是什么呢?
注意,我们在每次从数组取数据的时候,是使用交换的方式去数组中的元素。这个时候你的操作是对数组中的一些元素进行了交换了。
如果你在后边不把这些元素再交换回来,那么等你再次递归的时候会有可能拿到以前重复的元素的,举个例子:
{a,b,c}
我再取出a,以后,剩下了{b,c}。那么我继续取b,然后剩下c。这个时候输出abc;然后我开始回溯了,回到取b的地方这个时候进行本此调用
的for循环的第二次。注意,这个时候你是使用swap进行取元素的,那么你交换了b,c。所以顺利取出了c,然后接着就是b输出为acb。这个时候
因为b这个调用完成了,所以回溯到了a的地方。但是注意,这个时候你的数组变了变成了acb。所以,你接下来开始继续执行交换得到c,然后剩下
的元素组成的数组是{a,b},然后同样的递归得到了cab,cba,但是这个时候回溯到c的时候,这个时候数组友又变成了cba。然后接下来继续交换(第一个
和第三个交换)得到了a,然后剩下的元素是{b,c}这个时候跟第一次的结果是重复了!!!所以不加最后一句话是不行的。最后一句话保证你的操作的
自始至终是同一个数组。同一个排列。这样才可以从某个位置任选对应的数据才不会造成重复。
a(abc)
/ \
b(b,c)
/ \
c b(这个时候是cb)所以我在执行完以后必须还得还原原先对应的位置的数据。
*/
1
https://gitee.com/liyinxin/Algorithm.git
git@gitee.com:liyinxin/Algorithm.git
liyinxin
Algorithm
Algorithm
master

搜索帮助