树的遍历

Leetcode 题目总结:

感觉这是我写的无敌简洁的一版代码了,同时把难搞的后序遍历套上了前序的模版,思路更加清晰。

二叉树

二叉树的三序遍历。

前序遍历

先序:root->left->right,因此 left 需要放在栈顶。

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode*> s;
        s.push(root);
        while (!s.empty())
        {
            auto p = s.top();
            s.pop();
            res.push_back(p->val);
            if (p->right) s.push(p->right);
            if (p->left) s.push(p->left);
        }
        return res;
    }
};

中序遍历

极致压缩代码行数。需要注意的是:中序遍历,进入循环前不需要 s.push(p)

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        auto p = root;
        stack<TreeNode*> s;
        while (!s.empty() || p)
        {
            if (p) s.push(p), p = p->left;
            else p = s.top(), s.pop(), res.push_back(p->val), p = p->right;
        }
        return res;
    }
};

后序遍历

逆向考虑顺序:root, right, left ,这样可以套上先序遍历的模版(最后倒转 vector)。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        // postorder: left, right, root
        // first: root, right, left, which is similar to preorder
        // then: reverse the vector
        vector<int> res;
        if (root == nullptr) return res;
        auto p = root;
        stack<TreeNode*> s;
        s.push(p);
        while (!s.empty())
        {
            p = s.top(), s.pop();
            res.push_back(p->val);
            if (p->left) s.push(p->left);
            if (p->right) s.push(p->right);
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

层次遍历

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if (root == nullptr) return res;
        auto p = root;
        queue<TreeNode*> q;
        q.push(p);
        while (!q.empty())
        {
            vector<int> cur;
            queue<TreeNode*> next;
            while (!q.empty())
            {
                p = q.front(), q.pop();
                cur.push_back(p->val);
                if (p->left) next.push(p->left);
                if (p->right) next.push(p->right);
            }
            q = next;
            res.push_back(cur);
        }
        return res;
    }
};

先序

最左孩子放在栈顶。

class Solution {
public:
    vector<int> preorder(Node* root) {
        vector<int> res;
        if (root == nullptr) return res;
        auto p = root;
        stack<Node*> s;
        s.push(p);
        while (!s.empty())
        {
            p = s.top(), s.pop();
            res.push_back(p->val);
            auto &children = p->children;
            for (auto x = children.rbegin(); x!=children.rend(); x++)
                s.push(*x);
        }
        return res;
    }
};

后序

class Solution {
public:
    vector<int> postorder(Node* root) 
    {
        // postorder: child[l, ..., r] -> root
        // first: root -> child[r, ..., l], which is similar to preorder
        // then: reverse the vector
        vector<int> res;
        if (root == nullptr) return res;
        auto p = root;
        stack<Node*> s;
        s.push(p);
        while (!s.empty())
        {
            p = s.top(), s.pop();
            res.push_back(p->val);
            for (auto x: p->children) s.push(x);
        } 
        reverse(res.begin(), res.end());
        return res;
    }
};

层序

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> res;
        if (root == nullptr) return res;
        auto p = root;
        queue<Node*> q;
        q.push(p);
        while (!q.empty())
        {
            vector<int> cur;
            queue<Node*> next;
            while (!q.empty())
            {
                p = q.front(), q.pop();
                cur.push_back(p->val);
                for (auto x: p->children) next.push(x);
            }
            q = next;
            res.push_back(cur);
        }
        return res;
    }
};
posted @ 2020-04-08 21:31  sinkinben  阅读(261)  评论(0编辑  收藏  举报