[LeetCode] Binary Tree Traversal

目录

1. Binary Tree Traversal

1.1 Order types

1.2 Definition for a binary tree node

2 Recursive DFS Method

3 Iterative DFS Method with Stack

4. Morris Traversal

5 Level Traversal

5.1 Recursive method

5.2 Iterative method


1. Binary Tree Traversal

1.1 Order types

  1. Postorder: left->right->root
  2. Preorder: root->left->right
  3. Inorder:left->root->right

Tree Traverse

1.2 Definition for a binary tree node

Struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val (x), left(nullptr), right(nullptr) {}
};

2 Recursive DFS Method

  • Time complexity: O(N) ,  N is the number of nodes. We visit each node exactly once.
  • Space complexity:  O(H) ,  H is the height of the tree, in the worst case H = N.
vector<int> binaryTreeTraversal(TreeNode* root)
{
    vector<int> ans;
    DFSHelper(root, ans);
    return ans;
}

//Postorder
void DFSHelper(TreeNode* node, vector<int> &ans)
{
    if(!node) return;
    DFSHelper(node->left, ans);
    DFSHelper(node->right, ans);
    ans.push_back(node->val);
}

//Preorder
void DFSHelper(TreeNode* node, vector<int> &ans)
{
    if(!node) return;
    ans.push_back(node->val);
    DFSHelper(node->left, ans);
    DFSHelper(node->right, ans);
}

//Inorder
void DFSHelper(TreeNode* node, vector<int> &ans)
{
    if(!node) return;
    DFSHelper(node->left, ans);
    ans.push_back(node->val);
    DFSHelper(node->right, ans);
}

3 Iterative DFS Method with Stack

  • Time complexity: O(N) ,  N is the number of nodes. We visit each node exactly once.
  • Space complexity: O(N), we may have to keep the entire tree in stack.
vector<int>  postorderTraversal(TreeNode* root)
{
    vector<int> ans;
    stack<TreeNode*> todo_stk;
    TreeNode* curr = root;
    TreeNode* pre  = nullptr;
    while(curr || todo_stk.size()) {
        if(curr) {
            todo_stk.push(curr);
            curr = curr->left;
        } else {
            curr = todo_stk.top();
            if(curr->right && curr->right != pre) { //note
                curr = curr->right;
            } else {
                todo_stk.pop();
                ans.push_back(curr->val); //access
                pre = curr;
                curr = nullptr;
            }
        }
    }
    return ans;
}

vector<int> preorderTraversal(TreeNode* root)
{
    vector<int> ans;
    stack<TreeNode*> todo_stk;
    TreeNode* curr = root;
    while(curr || todo_stk.size()) {
        if(curr) {
            ans.push_back(curr->val); //access
            todo_stk.push(curr);
            curr = curr->left;
        } else {
            curr = todo_stk.top();
            todo_stk.pop();
            curr = curr->right;
        }
    }
    return ans;
}

vector<int> inorderTraversal(TreeNode* root)
{
    vector<int> ans;
    stack<TreeNode*> todo_stk;
    TreeNode* curr = root;
    while(curr != NULL || todo_stk.size()) {
        if(curr) {
            todo_stk.push(curr);
            curr = curr->left;
        } else {
            curr = todo_stk.top();
            todo_stk.pop();
            ans.push_back(curr->val); //access
            curr = curr->right;
        }
    }
    return ans;
}

Another way for iterative with stack


vector<int> preorderTraversal(TreeNode* root)
{
    if(!root) return {};
    vector<int> ans;
    stack<TreeNode*> todo_stk;
    todo_stk.push(root);
    while(todo_stk.size()) {
        TreeNode* top = todo_stk.top();
        todo_stk.pop();
        ans.push_back(top->val);
        if(top->right)
            todo_stk.push(top->right);
        if(top->left)
            todo_stk.push(top->left);
    }
    return ans;
}

4. Morris Traversal

  • Time complexity: O(N),  N is the number of nodes. But all predecessors were visited twice.
  • Space complexity: O(1)
vector<int> preorderTraversal(TreeNode* root)
{
    vector<int> ans;
    TreeNode* curr = root;
    TreeNode* prev = nullptr;
    while(curr) {
        if(curr->left) {
            prev = curr->left;
            while (prev->right && prev->right != curr)
                prev = prev->right;

            if(prev->right == NULL) { //first visit
                ans.push_back(curr->val);
                prev->right = curr;
                curr = curr->left;
            } else {                  //second visit
                prev->right = nullptr;
                curr = curr->right;
            }
        } else {
            ans.push_back(curr->val);
            curr = curr->right;
        }
    }
    return ans;
}

vector<int> inorderTraversal(TreeNode* root)
{
    vector<int> ans;
    TreeNode* curr = root;
    TreeNode* prev = nullptr;
    while(curr) {
        if(curr->left) {
            prev = curr->left;
            while (prev->right && prev->right != curr)
                prev = prev->right;
            
            if(prev->right == NULL) {
                prev->right = curr;
                curr = curr->left;
            } else {
                ans.push_back(curr->val);
                prev->right = nullptr;
                curr = curr->right;
            }
        } else {
            ans.push_back(curr->val);
            curr = curr->right;
        }
    }
    return ans;
}

5 Level Traversal

5.1 Preorder Recursive method

  • Time complexity: O(N)
  • Space complexity: O(logN), logN is the stack memory cost
vector<vector<int>> levelOrder(TreeNode* root)
{
    vector<vector<int>> ans;
    DFSHelper(root, 0, ans);
    return ans;
}

void DFSHelper(TreeNode * root, int depth, vector<vector<int>> &ans)
{
    if(!root) return;
    if(ans.size() == depth)
        ans.push_back({});
    ans[depth].push_back(root->val);
    DFSHelper(root->left, depth+1, ans);
    DFSHelper(root->right, depth+1, ans);
}

5.2 Iterative method

  • Time complexity: O(N)
  • Space complexity: O(2^{logN}), logN is the height of the tree
vector<vector<int>> levelOrder(TreeNode* root)
{
    if(!root) return {};
    vector<vector<int>> ans;
    queue<TreeNode*> todo_q;
    todo_q.push(root);
    while(todo_q.size()){
        int n = todo_q.size();
        ans.push_back({});
        for (int i = 0; i < n; i++) {
            TreeNode* node = todo_q.front();
            todo_q.pop();
            ans.back().push_back(node->val);
            if(node->left) todo_q.push(node->left);
            if(node->right) todo_q.push(node->right);
        }
    }
    return ans;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值