题目描述
Given the root of a binary tree, return the inorder traversal of its nodes' values.
Example 1:
Input: root = [1,null,2,3]
Output: [1,3,2]
Example 2:
Input: root = [1,2]
Output: [2,1]
Example 3:
Input: root = []
Output: []
Constraints:
The number of nodes in the tree is in the range [0, 100].
-100 <= Node.val <= 100
Follow up:
Recursive solution is trivial, could you do it iteratively?
解法一:递归
解题思路
题意:由题给的二叉树求得其中序遍历序列。
题给节点类型TreeNode:val为节点序号,left为左子节点,*right为右子节点。【e.g. TreeNode* node; 则节点序号为node->val;节点左子节点为node->left;节点右子树为node->right】
题目要求写的函数vector<int> inorderTraversal(TreeNode* root)作用:返回一存储了题给二叉树中序遍历序列的vector<int>类型数组。【递归解法中在vector<int> inorderTraversal(TreeNode* root)函数中调用完成中序遍历并填充结果数组的递归函数void inorder(TreeNode* root, vector<int> &rst)。】
递归思路:从根节点开始,对每个访问到的节点node:①访问其左子节点 ②把自己放入结果 ③访问其右子节点 ④倒退回前一个节点,直到访问完成所有节点。也就是说,从根节点开始,对每个访问到的节点node,优先访问其左子树,抵达其最左侧子节点左侧空节点(即通过递归出口),将当前空节点的根节点(即最左侧子节点→→→即未访问节点中最左节点)存入结果,再访问node节点右子树——完成对node节点的左中右访问后,倒退回node节点的前一个节点——直到访问完毕所有节点。
提交代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
void inorder(TreeNode* root, vector<int> &rst)
{
if(!root) return; //当前无root节点,说明当前路已经走到头,需开始递归倒退回上一个节点
inorder(root->left, rst); //对于每个结点,先访问其左子树(直到最左节点后往回递归)
rst.push_back(root->val); //完成当前左子树访问后抵达的root节点即当前最左,存入结果
inorder(root->right, rst); //访问过当前左子树和root节点后即访问右子树
}
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> rst;
inorder(root, rst);
return rst;
}
};
解法二:栈
解题思路
题意及基本介绍如上。
将每个节点标记为0:未访问过,或1:已访问过。
初始入栈根节点。
当栈不为空时,若栈顶节点未被访问过,则使其右子节点、自身、左子节点入栈,并将自身标记为已访问;若栈顶节点已被访问过,则记入结果。
提交代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> rst; //存储题给二叉树中序遍历序列的结果数组
stack<pair<TreeNode*, int> > stk; //二维栈【节点,标记(0为未访问;1为已访问)】
stk.push(make_pair(root, 0)); //根节点标记为未访问,入栈
while(!stk.empty())
{
auto [node, type]=stk.top(); //node和type保存当前栈顶节点的节点和类型
stk.pop(); //栈顶节点出栈
if(node==nullptr) continue;
if(type==0) //如果栈顶节点node标记为未访问
{
stk.push(make_pair(node->right, 0)); //node右子节点入栈
stk.push(make_pair(node, 1)); //标记node节点为已访问
stk.push(make_pair(node->left, 0)); //node左子节点入栈
}
else //如果栈顶节点node标记为已访问,则说明其左右子节点都已在栈中,将node节点记入结果
rst.push_back(node->val);
}
return rst;
}
};
P.S.
还有官方题解里给的Morris中序遍历,回头在写。