双递归(两个递归深入点)函数的执行顺序——分组问题为例

9 篇文章 1 订阅
4 篇文章 3 订阅

一.分组问题

  1. 题目:用递归法计算从n个人中选选k个人组成一个委员会的不同组合数。
  2. 分析:n个人里选k个人的组合数 n-1个人里选k个人的组合数 n-1个人里选k-1个人的组合数;n = kk = 0时,组合数为1
#include <iostream>
using namespace std;
/*双递归的执行过程,可以借助二叉树结构来描述*/
int comm(int n, int k) {//排除n < k的情况
	if (n < k) {
		return 0;
	}
	else if(n == k || k == 0)//递归函数的出口
	{
		return 1;
	}
	else {//两个递归深入点,但是同函数中左右深入点的深入层次并不一定相同
		return comm(n - 1, k) + comm(n -1, k - 1);
	}
}

int main() {
	int n, k;
	cin >> n >> k;
	cout << comm(n, k);
	system("pause");
	return 0;
}

二.双递归函数的执行顺序

双递归的执行过程,可以借助二叉树结构来描述:

二叉树描述双递归执行过程

  1. 程序从首先左端的递归深入点进入,再次调用函数(4, 3),再次从左侧深入点(3, 3)深入。此时得到第一个递归的终止条件:n = k,组合数为1,将1返回给父级节点;在此之前,(4, 3)右端的函数深入点并未执行,而是作为没有执行完毕的函数被保存在栈中。此时则是执行(4, 3)右侧递归深入点(3, 2)函数。剩余执行过程由红色箭头标识,不再一一说明。
  2. 无论执行左侧还是右侧函数,调用时必定先执行左子树所代表的函数。若此时这棵左子树依然存在后代,则先执行它的左子树函数,然后循环此逻辑;直到左子树没有下级节点时,那么就返回它的上级节点,来执行上级节点的右子树函数。
  3. 使用二叉树表示的双递归函数执行过程中,任何一个节点若存在子节点,那么它的左后代与右后代必然是同时存在的。原因就在于在递归调用函数时,两个调用自身的函数也是同时存在的。
  4. 当一个节点找到递归出口时,那么与它有相同父级节点的兄弟节点不会停止递归深入,直到得到一个可以返回的值为止(即找到递归出口)。所以,叶子结点返回值逐级累加,所有的返回值之和,就是题目所求结果,也就是整个递归最外层函数的返回值即函数调用者(此题为main函数)所需要的结果。
  5. 可以使用断点调试对变量进行监视,从而更好地理解双深入点递归函数的执行过程。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值