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号