【笔记】递归问题

递归问题✨
Recursion

🏳‍🌈写在前面:
递归是自入门算法以来(虽然也没有很久)碰到的第一个想着想着就蒙了的东西😶,因为看的是算法竞赛书,第一道例题的代码啃了两三天也没搞懂,后来也不知道怎么了,盘着腿叉着腰就突然看懂了(hhh,和姿势无关),下面一些文字就分享一下自己递归入门的过程吧!🙃

定义
正儿八经的百度百科上就有,我在维基百科上看到的一个语言例子把我给看乐了:
⚡一只狗来到厨房,偷走一小块面包。厨子举起杓子,把那只狗打死了。于是所有的狗都跑来了,给那只狗掘了一个坟墓,还在墓碑上刻了墓志铭,让未来的狗可以看到:“一只狗来到厨房,偷走一小块面包。厨子举起杓子,把那只狗打死了。于是所有的狗都跑来了,给那只狗掘了一个坟墓,还在墓碑上刻了墓志铭,让未来的狗可以看到……”
但是作为计算机算法,需要满足有穷性,因此写递归的时候需要加上停止条件。

例题:递归打印1,2,3,4,5的全排列
(把我绕晕的例题,也是很经典的一个例题)

分析
依愚拙见,看递归代码尽量不要加断点一步步调,我一开始这么干是真的晕(也可能是我菜),不过依照某大佬的建议,画调用数,先用1,2,3排列做试了一下,但这是在我已经弄懂的情况下再做,虽然没那么蒙圈,但我觉得还是有点绕。我的思路如下:
⚡第一步:明白递归的主体思路
⚡第二步:明白递归需在何时停止
⚡第三步:明白下一次递归(即问题往小了化解)时的条件
👍知道了这三步,就基本完成了对一个递归程序的构造
接下来只需要套框架:(部分代码依据题目难度省略或添加)

int perm(形参1){
	if(结束条件){
		结束前想做的,如这题是打印出全排列
		return 0}
	else{
		主体代码块,其中包含:
		perm(形参2); //这里的形参一定是能将大问题分解为小问题的参数
	}
	return 0;
}

本题代码及解读:

#include<bits/stdc++.h>
using namespace std;
#define Swap(x,y) {int t=x;x=y;y=t;} //也可使用C++STL库中的swap函数,但效率较低

int a[]={1,2,3,4,5}; //要排列的五个数

int Perm(int begin,int end){
    if(begin==end){  //停止条件
        for(int i=0;i<5;i++) 
        	printf("%d ",a[i]);
        cout<<endl;
    }
    else{
        for(int i=begin;i<end;i++){
            Swap(a[begin],a[i]);
            Perm(begin+1,end);
            Swap(a[begin],a[i]);
        }
    }
    return 0;
}

int main(){
    Perm(0,5);
    return 0;
}

比较难懂的应该就是else语句里的for循环部分了,但是不要一步步把数字带进去看。因为我们明白了程序是在begin=end时结束,所以只需弄清楚大问题如何转化为小问题就行了,而这里恰恰就是问题的关键:
易知两句Swap语句之后排列不变,中间的Perm只是将begin+1送入下一个小问题,所以大问题就是perm(begin,end)小问题就是perm(begin+1,end),而他们之间的转化关系就是Swap(a[begin],a[i]),而此处 i ∈ [ b e g i n , e n d ] i\in[begin,end] i[begin,end],所以说这道题的大问题会转化为多个小问题
这样我们就清楚了整个问题的内部逻辑,用图来表示就是:

1
2
3
4
5
2
3
4
5
3
4
4
5
5
4
5
1,2,3,4,5
2,3,4,5
1,3,4,5
1,2,4,5
1,2,3,5
1,2,3,4
3,4,5
2,4,5
2,3,5
2,3,4
4,5
3,5
3,4

这里只列出了一部分,但应该是能很好地理解整个大问题到小问题的分解,因此整个问题迎刃而解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值