【LeetCode】 94 Binary Tree Inorder Traversal

这篇博客介绍了如何解决LeetCode中的94题,即给定一个二叉树,返回其节点值的中序遍历。首先,详细解释了递归解法的思路,然后提供了迭代解法的实现,利用栈来完成中序遍历。此外,还提到了后续会讨论的Morris中序遍历方法。
摘要由CSDN通过智能技术生成

题目描述

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中序遍历,回头在写。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值