c++编程——递归编程

递归实现

实现递归编程的方法,需要三步(第2和第3可以同时思考):

  1. 明确函数作用是什么
  2. 递归的条件表达式
  3. 递归结束的条件

用三个具体的例子做具体分析:

  • 计算n的阶乘
  • 斐波那契数列
  • 查找二叉树最大的节点

example 1: 计算n的阶乘

Q1:函数作用是什么?
计算n的阶乘,返回结果—— 确定函数及返回值

long long factorial(int n) {
	long long res;

	return res;
}

Q2:递归的条件表达式
factorial(n) = factorial(n-1)*n

long long factorial(int n) {
	long long res;

	res = factorial(n-1)*n;
	return res;
}

Q3: 递归结束的条件
factorial(1) = 1;

long long factorial(int n) {
	long long res;
	if (n==1)
		return 1;
	res = factorial(n-1)*n;
	return res;
}

最后,对代码进行一下整理

long long factorial(int n) {
	if (n==1)
		return 1;
	return factorial(n-1)*n;
}

example 2: 斐波那契数列

Q1:函数作用是什么?
计算斐波那契数列第n个数,返回结果—— 确定函数及返回值

int fibonacci(int n) {
	
	return;
}

Q2:递归的条件表达式
fibonacci(n) = fibonacci(n-1) + fibonacci(n-2)

int fibonacci(int n) {
	
	return fibonacci(n-1) + fibonacci(n-2);
}

Q3: 递归结束的条件
fibonacci(1) = 1;
fibonacci(2) = 1;

int fibonacci(int n) {
	if (n==1)
		return 1;
	if (n==2)
		return 1;
	return fibonacci(n-1) + fibonacci(n-2);
}

注意:这里只是用fibonacci数列作为例子,实际开发中fibonacci求结果不应该使用递归来实现。因为在递归过程中,太多运算被重复,时间复杂度变得很夸张,不推荐使用。

example 3: 查找二叉树最大的节点

Q1:函数作用是什么?
找到二叉树最大节点,返回这个节点—— 确定函数及返回值

class TreeNode {
public:
    int val;
    TreeNode* left, * right;
    TreeNode(int val) {
        this->val = val;
        this->left = this->right = NULL;
    }
};

TreeNode* maxNode(TreeNode* root) {

    return node;
}

Q2:递归的条件表达式
遍历左子树,找到最大值。
遍历右子树,找到最大值。
比较root,左子树最大值,右子树最大值

class TreeNode {
public:
    int val;
    TreeNode* left, * right;
    TreeNode(int val) {
        this->val = val;
        this->left = this->right = NULL;
    }
};

TreeNode* maxNode(TreeNode* root) {

	TreeNode* left = maxNode(root->left);
	TreeNode* right = maxNode(root->right);
	
    return max(root, max(left, right));
}

Q3: 递归结束的条件
当某一节点为NULL时,即其父节点到底,开始回归。

class TreeNode {
public:
    int val;
    TreeNode* left, * right;
    TreeNode(int val) {
        this->val = val;
        this->left = this->right = NULL;
    }
};

TreeNode* maxNode(TreeNode* root) {

	if (root == NULL)
		return root;
	
	TreeNode* left = maxNode(root->left);
	TreeNode* right = maxNode(root->right);
	
    return max(root, max(left, right));
}

上面的代码,部分是伪代码,进行细节优化

class TreeNode {
public:
    int val;
    TreeNode* left, * right;
    TreeNode(int val) {
        this->val = val;
        this->left = this->right = NULL;
    }
};

TreeNode* maxNode(TreeNode* root) {

	if (root == NULL)
		return root;
	
	TreeNode* left = maxNode(root->left);
	TreeNode* right = maxNode(root->right);
	
    return max(root, max(left, right));
}

 TreeNode* max(TreeNode* a, TreeNode* b) {
 	 //考虑左节点为NULL
     if (a == NULL)
         return b;
     //考虑右节点为NULL
     if (b == NULL)
         return a;
     //考虑左右节点都不为NULL
     if (a->val > b->val) {
         return a;
     }
     return b;
 }

对于上面的max函数,未考虑左右节点均为NULL情况,看一下原因:
当这种状况出现时, max(left, right)) 返回NULL。
然后执行,max(root, NULL),root肯定不为NULL,所以不会出现故障报错。<root为NULL时,程序不会执行到这里>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值