设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。

问题描述:

设计一个递归算法生成n个元素{r1,r2,,rn}的全排列。

全排列:将n个不同元素按一定的顺序排列起来,所能形成的所有排列情况

算法思路:

R={r1,r2,,rn}是要进行排列的n个元素,Ri=R-{ri}

集合X中元素的全排列记为perm(X)

(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。R的全排列可归纳定义如下:

n=1时,perm(R)=(r),其中r是集合R中唯一的元素;

n>1时,perm(R)(r1)perm(r1)(r2)perm(r2)(rn)perm(rn)构成。

为什么这么设,我们要遍历所有排列情况,先把第一个元素放在第一位,然后剩下的所有元素中依次填入第二位,以此类推,求出的是第一个元素在首位的所有情况,剩下的所有情况与之步骤相似,依次求出第二、第三到第n个元素在首位时的所有情况,此时遍历完成。

例如:1 2 3的全排列

先把1放在首位,然后剩下的有两种情况,2或3放在第二位,剩下的那个数放在第三位,这样就遍历了所有1在首位的情况;

然后同第一步,依次把2、3放在首位,求出剩余元素的排列情况;

此时所有情况相加就是总的全排列的情况

核心代码:

Void Perm(Type list[],int k,int m){
//k为头,m为尾
if(k==m){//为真即表示剩余最后一个元素,此时输出排列情况
  for(int i=0;i<=m;i++){
    cout<<list[i];
  }
}
else{
  for(int i=k;i<=m;i++){//从k到m,依次把每个数放在当前所有元素的首位,然后求剩余元素的所有排列情况
    swap(list[k],list[i]);//依次放在当前所有元素首位k,同时原本首位的值暂时先放到它空缺的位置上算做剩余元素
    perm(list,k+1,m);//剩余的所有元素求全排列,继续把每个元素依次放在当前的首位,进行递归
    swap(list[k],list[i]);//完成之后再把之前暂时放在首位的值交换回去,变回原位,便于下一个数的操作
  }
}
}

总结:

递归算法就是把问题大而化之,就像本题,求全排列的所有情况,我们的遍历方式就是依次把每个数放在第一位,然后剩余元素继续全排列,剩余元素求全排列继续这样遍历,这里就是几乎相同的操作了,这样就可以一步步递归,从而把问题分解。当然,递归里面非常重要的前提是弄清楚边界,这道题里的边界就是km,即头尾指针相等时,只剩一个元素了,这个时候递归就结束了。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值