1.1.5 二叉树
//二叉树结点定义:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
144. Binary Tree Preorder Traversal
二叉树的先根序遍历
94. Binary Tree Inorder Traversal
二叉树的中根序遍历
145. Binary Tree Postorder Traversal
二叉树的后根序遍历
- 初学阶段,我们选择用递归实现上面三种二叉树遍历。
- 与上面几节想缕清思路再写代码方式不同,我们在二叉树环节先给出代码,然后一起看下代码代表的思路是什么。
- 尽量体会递归是怎样实现的。
- 如果你感觉下面的流程示意图看起来有些困难,可以跳过他们,在后面的过程中我们还会逐步学习
1.举例子-画图-解题思路
//这段代码就是二叉树遍历的核心,从根节点开始,先递归遍历左子树,再递归遍历右子树
void traversal(TreeNode* root)
{
if(!root) return;
traversal(root->left);
traversal(root->right);
}
我们继续从例子来看下上面递归的过程,有这样一颗二叉树
当将root节点,即a节点传到函数traversal时,程序运行过程如下所示:
递归函数过程描述 (1).png
- 箭头上的数字标明了函数执行步骤
- 递归是一个不断“递”和“归”的过程。红色箭头表示“递”,即层层递进调用函数;黑色箭头表示“归”,表示满足函数返回条件,返回上一层函数。
- 递归时,下层函数满足条件能返回上层是借助了系统的栈来实现的。
从栈的角度来理解上面的函数调用过程
递归的实现-栈.png
2. 写核心逻辑代码
二叉树的先根序,中根序,后根序遍历,只是在上面递归过程中打印结点的时机不同:
//144题目 先根序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return result;
preorder(root);
return result;
}
void preorder(TreeNode* root)
{
if(!root) return;
//在递归遍历左右结点前,把根结点放入vector中
result.push_back(root->val);
preorder(root->left);
preorder(root->right);
}
private:
vector<int> result;
};
//vector中字母顺序:a b e f c
//94题目 中根序
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
if(!root) return result;
inorder(root);
return result;
}
void inorder(TreeNode* root)
{
if(!root) return;
inorder(root->left);
//先递归遍历完左结点,再把根结点放入vector中
result.push_back(root->val);
inorder(root->right);
}
private:
vector<int> result;
};
//vector中顺序为e b f a c
//145题目,后根序遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return result;
postorder(root);
return result;
}
void postorder(TreeNode* root)
{
if(!root) return;
postorder(root->left);
postorder(root->right);
//递归遍历完左右结点后再把根结点放入vector中
result.push_back(root->val);
}
private:
vector<int> result;
};
//vector中顺序为e f b c a
3. 边界条件-无
4. 优化-无
5. 小结
- 理解二叉树的先根、中根、后根遍历,最好先了解递归的基本思想。先根、中根、后根的区别只是在于在递归过程中打印结点的时机不同。
- 递归概念在代码实现上比较简洁,但内部的递归调用比较复杂,现在不理解也没关系,我们在后续的练习还会接触到递归的使用
怎样应对IT面试与笔试-(一)
怎样应对IT面试与笔试-(二)
怎样应对IT面试与笔试-(三)
怎样应对IT面试与笔试-(四)
怎样应对IT面试与笔试-(五)
怎样应对IT面试与笔试-(五-1)
怎样应对IT面试与笔试-(六)
怎样应对IT面试与笔试-(七)
怎样应对IT面试与笔试-(八)
怎样应对IT面试与笔试-(九)
怎样应对IT面试与笔试-(十)
怎样应对IT面试与笔试-(十一)
怎样应对IT面试与笔试-(十二)
怎样应对IT面试与笔试-(十三)
怎样应对IT面试与笔试-(十四)
怎样应对IT面试与笔试-(十五)
怎样应对IT面试与笔试-(十六)
网友评论