严格按照这三步, 轻松解决递归问题
很多时候困扰我们的
?在写递归函数前, 我们先要给要写的这个递归函数下一个定义.
一旦下完了这个定义, 我们就认为函数具有了这个功能(尽管这个函数我们并未书写)
然后在书写代码的时候就帮这个被我们下过定义的函数当成具有这个功能的函数来写
注意: 不要过分的关注函数本身, 下完定义, 函数就具有这个功能, 不需要纠结如何实现
就以二叉树的前序遍历为例子, 我们给这个函数下一个定义, 就是前序遍历这棵二叉树
class TreeNode { public: TreeNode* left; TreeNode* right; int val; } // 来给函数下一个定义 void bfs(TreeNode* root); // 该函数的功能: 前序遍历以root为根节点的这棵二叉树
在下完定义以后, 就可以来分析函数该做什么了
cout << root->val << endl;
注意! 注意! 注意!
这里是重点
我们来回顾一下刚刚给bfs(TreeNode*)函数下的定义: // 该函数的功能: 前序遍历以root为根节点的这棵二叉树
我们下完定义, 就应该默认这个函数具有了这个功能
因此, 我们要实现前序遍历root的左右子节点, 就只需要用我们刚刚下过定义的这个函数
bfs(root->left);// 前序遍历left子树 bfs(root->right);// 前序遍历right子树
再说一遍!再说一遍!下完定义之后我们就应该把函数当成有我们下定义的这个功能, 尽管我们函数一点没写
最后, 我们需要判断一下, 2中所做的事情的顺序
接着以二叉树的前序遍历为例子, 2中我们已经分析完了, 要做3件事
1
2
3
这棵树前序遍历的结果应该是
1 2 3 5 7 3 6 8 9
应该不难想到:
1
2
3
所以执行的顺序就是 1
→2
→ 3
那么这个函数的大致轮廓就出来了
void bfs(TreeNode* root); { cout << root->val << endl; bfs(root->left);// 前序遍历left子树 bfs(root->right);// 前序遍历right子树 }
边界问题一般不难分析
还是说这棵树, 应该不难看出, 当root值为nullptr的时候, 这个函数就应该推出了
if(root == nullptr) { return; }
@brief 前序遍历一棵二叉树 void bfs(TreeNode* root); { if(root == nullptr) { return; } cout << root->val << endl; bfs(root->left);// 前序遍历left子树 bfs(root->right);// 前序遍历right子树 }