程序递归的本质-------第二类数学归纳法

本文介绍了递归在算法中的重要性,结合第二类数学归纳法,概述了如何在程序中正确使用递归,包括设定递归停止条件和完成最终递归步骤。通过代码示例演示了如何计算二叉树第K层节点的数量,展示了递归解决问题的逻辑过程。
摘要由CSDN通过智能技术生成

前言

在算法学习过程中,递归作为一种有着神奇力量的算法技巧,它虽然有着难以接受的缺点:会产生大量重复计算,浪费时间又或是对空间的过度使用,导致栈溢出等,但是再解决一些复杂嵌套的问题时有着无可替代的作用:通过简单逻辑实现复杂遍历与操作。
递归这一个技巧的本质是第二类数学归纳法,下面通过数学和程序员的双重角度,带你总结递归的两步模板,保证看过之后,秒杀这类题目。

一、第二类数学归纳法是什么?

一到是什么的问题,就不可避免的要讨论定义问题,虽然看定义很枯燥,但是这是一个丰富内功的过程,具体严格的定义,要知道的话百度查一下就可以,这里我就不赘述了,就用我自己的话解释一下,就是数学归纳法的证明分两步;
1.假设你已经证明了前k-1步都是正确的,若证明第k步是正确的,你要用到第k-1,k-2…k-n(k>n)步,那么你需要先证明前n步是正确的,这是一切的基底。
2.然后再在前k-1之前的步都已经证明的条件下,证明第k步是正确的。
这样就证明完毕,看着是不是有点复杂,其实n一般就是2或者3,所以简单来说就是先证明前面几步,再证明k就可以了。

二、在程序中具体如何使用

1.写出递归停止条件

递归需要有一个任何情况都可执行完的递归条件,这一个是不可避免的,而这个递归条件和数学归纳法有什么关系呢?这个就是数学归纳法要证明的前n个,也就是能归纳进行的基底。而这个方法的第一步就是写出不需要递归的结束条件(直接停止条件)。

2.完成最后一步

条件写完,基本就已经完成程序的大部分了,根据数学归纳法,前n个你已经证明了,那么只需要证明k就行,这在程序上的表现是只需要完成最后一个递归,即假设你的递归函数已经完成了,你只需调用它完成第一步就可以了,这实际上是给程序一个基底使用的逻辑。

代码示例展示

听起来很简单吧,下面来尝试一下对线简单的代码吧!

typedef char BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;//二叉树结构体
int BinaryTreeLevelKSize(BTNode* root, int k)
{
//1.
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
//2.
	return BinaryTreeLevelKSize(root->left, k - 1) + BinaryTreeLevelKSize(root->right, k - 1);
}

这是一个计算第K层节点的个数的函数,如何实现的呢?
首先第一步,写出递归停止条件,显然:如果遍历到空返回0,如果计算根的这一层的节点就返回1。
然后第二步,递归的强势点发力了,虽然这个函数还没有实现,但你可以调用它,并且只需要完成第一步就可以,换言之如果你要计算这个二叉树第K层的节点个数,你的限制只是不可以调用这个函数直接求二叉树这个树的第K层节点,但是调用这个函数求他的分支二叉树的第K层节点是可以的。
那么二叉树的第K层节点点等于什么呢?显然:左右分支的第K-1层节点+1。
上面代码的例子虽然很简单,但是复杂代码也是一样的,复杂递归的难度就是在找递归停止条件是什么,而这个过程是不可避免的,知道这个方法你可以明确的知道下一步你该做什么,可以系统的写出一个完美且自信的递归代码,而不是逻辑在脑中混乱地过一遍,然后直接写,最后成不成看天命😀

总结

上面的方法是不是很简单呢?
总结一下,这个方法就是有两步
1.明确什么条件下递归终止(这个条件是直接停止条件,作为递归逻辑的基底)。
2.调用这个函数实现主程序(就是最开始给的程序,二叉树为例,就是开始给的那个二叉树)。

找几个题试一下吧【微笑】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值