中序遍历 94. Binary Tree Inorder Traversal
程序员文章站
2022-05-20 13:45:13
...
方法一:堆栈解决,不修改原节点
vector<int> inorderTraversal(TreeNode* root) {
//堆栈解法 时间O(n)
vector <int> res;
TreeNode *curroot=root;
stack<TreeNode *>s;
while(curroot||!s.empty()){
if(curroot){
s.push(curroot);
curroot=curroot->left;
}
else{
TreeNode *node=s.top();
s.pop();
res.push_back(node->val);
curroot=node->right;
}
}
return res;
}
方法二递归解决
vector<int> inorderTraversal(TreeNode* root) {
vector <int> res;
inorder(root,res);
return res;
}
private:
void inorder(TreeNode* root,vector<int>&res){
if(!root)return ;
inorder(root->left,res);
res.push_back(root->val);
inorder(root->right,res);
}
方法三 O(1) SPACE O(N)TIME 中文解释 Morris Traversal
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
TreeNode *curNode=root;//遍历的当前节点
vector<int> res;
while(curNode){
if(curNode->left){//中序 左根右 所以先检查有没有左节点
//由于我们没有申请栈来保存当前节点的父节点
//但是我们必须保存我们需要的父节点,所以这里我们把父节点存储到当前节点的最右节点,也是根据中序遍历当前节点遍历的最后一个节点,当前节点最右节点的下一个节点是其父节点
TreeNode *preNode=curNode->left;//记录当前节点
while(preNode->right&&preNode->right!=curNode){
//寻找当前节点的最右节点,保存当前节点的父节点curNode
//这里有可能会寻找到保存的父节点 如果最右节点是父节点,则退出,恢复原来的二叉树
preNode=preNode->right;
}
if(!preNode->right){//最右节点的右节点为空
//把父节点存在当前节点的最右节点
preNode->right=curNode;
//遍历下一个节点 左根右 先左
curNode=curNode->left;
}
else{//如果最右节点为父节点,也就是preNode->right=curNode则恢复原来的二叉树,将最右节点指向空
preNode->right=NULL;
//把当前节点值保存 根
res.push_back(curNode->val);
//当前节点的左部分已经遍历完成,现在遍历右面
curNode=curNode->right;
}
}
else{//如果左节点为空 根据左跟右 当前节点可以称之为根节点,把当前节点值保存,然后遍历当前节点的右节点
res.push_back(curNode->val);
curNode=curNode->right;
}
}
return res;
}
};