二叉树的遍历总结

人走茶凉 提交于 2019-12-11 04:45:37

二叉树的遍历总结

前序遍历[leetcode144]

遍历方式:“根结点-左孩子-右孩子”

递归(Recursive)

/**
 * 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> preorderTraversal(TreeNode* root) {
        vector<int> res, left, right;
        if (!root) return res;

        res.push_back(root->val);

        left = preorderTraversal(root->left);
        for (auto& x : left) res.push_back(x);

        right = preorderTraversal(root->right);
        for (auto& x : right) res.push_back(x);

        return res;
    }
};

迭代(Iterative)

遍历方式:

  • 从根节点开始,开始遍历,并输出(先序遍历首先输出根)

  • 递归输出直至最左(先序根后面输出的是左孩子)

  • 当到达最左节点的时候,访问右节点

处理过程:

  • 访问结点P,并将结点P入栈;

  • 判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;

  • 直到P为NULL并且栈为空,则遍历结束。

/**
 * 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> preorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        
        while (root || !stk.empty())
        {
            while (root)
            {
                stk.push(root->right);
                res.push_back(root->val);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
        }
        return res;
    }
};

中序遍历[leetcode94]

遍历方式:“左孩子-根结点-右孩子”

递归(Recursive)

/**
 * 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> preorderTraversal(TreeNode* root) {
        vector<int> res, left, right;
        if (!root) return res;

        

        left = preorderTraversal(root->left);
        for (auto& x : left) res.push_back(x);

        res.push_back(root->val);

        right = preorderTraversal(root->right);
        for (auto& x : right) res.push_back(x);

        return res;
    }
};

迭代(Iterative)

/**
 * 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) {
        vector<int> res;
        stack<pair<TreeNode*, int>> stk;
        stk.push(make_pair(root, 0));

        while (!stk.empty())
        {
            if (stk.top().first == NULL)
            {
                stk.pop();
                continue;
            }
            int t = stk.top().second;
            if (t == 0)
            {
                stk.top().second = 1;  // t = 1; 超时了
                stk.push(make_pair(stk.top().first->left, 0));
            }
            else if (t == 1)
            {
                res.push_back(stk.top().first->val);
                stk.top().second = 2;
                stk.push(make_pair(stk.top().first->right, 0));

            }
            else stk.pop();

        }
        return res;
    }
};
/**
 * 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) {
        vector<int> res;
        stack<TreeNode*> s;
        auto now = root;
         while (now || !s.empty()) {
            while (now){
                s.push(now);
                now = now->left;
            }
            if (!s.empty()){
                now = s.top();
                s.pop();
                res.push_back(now->val);
                now = now->right;
                }
         }
        return res;
    }
};

后序遍历[leetcode145]

遍历方式:“左孩子-右孩子-根结点”

递归(Recursive)

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
/**
 * 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> postorderTraversal(TreeNode* root) {
      vector<int> res, left, right;
      if(!root) return res;

      left = postorderTraversal(root->left);
      for(auto &x : left) res.push_back(x);

      right = postorderTraversal(root->right);
      for(auto &x : right) res.push_back(x);

      res.push_back(root->val);

      return res;
    }
};

迭代(Iterative) O(n)O(n)

非递归算法需要一个栈

/**
 * 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> postorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        if (!root) return res;

        TreeNode* cur = root, *lastVisited = NULL;

         while (cur != NULL || !stk.empty()) {
            while (cur != NULL) {
                stk.push(cur);
                cur = cur->left;
            }
            cur = stk.top(); 
            if (cur->right == NULL || cur->right == lastVisited) {
                stk.pop();
                res.push_back(cur->val);
                lastVisited = cur;
                cur = NULL;
            } else {
                cur = cur->right;
            }
        }
        return res;

    }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!