leetcode 94. 二叉树的中序遍历(递归 迭代 morris)
链接;https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
题目
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例
示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[2,1]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
思路
方法1:
标准的递归深搜题
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        ans.clear();
        dfs(root);
        return ans;
    }
private:
    vector<int>ans;
    void dfs(TreeNode*root){
        if(root==nullptr)
            return;
        dfs(root->left);
        ans.push_back(root->val);
        dfs(root->right);
    }
};
方法2:
如果不使用递归,可以用迭代的方法
建立一个栈模拟递归的过程,不过循环的条件要注意(一直往左 遇空输出退格往右检索一次)
注意遍历条件(!s.empty()||root!=nullptr)
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int>ans;
        stack<TreeNode*>s;
        while(!s.empty()||root!=nullptr)//把每次遍历到左子树的最右侧结束
        {
            while(root!=nullptr)
            {
                s.push(root);
                root=root->left;
            }
            root=s.top();
            s.pop();
            ans.push_back(root->val);
            root=root->right;
        }
        return ans;
    }
};
方法三
若要空间数为o(1)
可以使用morris遍历,对树的结构进行修改,将目标节点左子树的最右子树的右子树指针连接到目标节点,来节省空间
循环过程中每个点其实遍历过两次
第一次是root和root左子树上寻找最右子树的指针predecessor建立链接的过程
第二次遍历是root到达左子树尽头时开始输出答案过程,输出当前点,再顺着右子树到上一节点解除子节点的链接
所以判断条件为 (predecessor->right != nullptr && predecessor->right != root)
class Solution {
public:
    vector<int> inorderTxu
        while (root != nullptr) {
            if (root->left != nullptr) {
                // predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
                predecessor = root->left;
                while (predecessor->right != nullptr && predecessor->right != root) {
                    predecessor = predecessor->right;
                }
                
                // 让 predecessor 的右指针指向 root,继续遍历左子树
                if (predecessor->right == nullptr) {
                    predecessor->right = root;
                    root = root->left;
                }
                // 说明左子树已经访问完了,我们需要断开链接
                else {
                    res.push_back(root->val);
                    predecessor->right = nullptr;
                    root = root->right;
                }
            }
            // 如果没有左孩子,则直接访问右孩子
            else {
                res.push_back(root->val);
                root = root->right;
            }
        }
        return res;
    }
};
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号