算法(二叉树)

引言

本篇文章讲的是二叉树的一些基础代码,

二叉树的非递归遍历代码

前序遍历

前序遍历我们用栈来处理,因为是根左右,所以我们应该先把右节点放进去

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        if (root == nullptr) {
            return {};
        }
        stack<TreeNode*> st;
        st.push(root);
        vector<int> res;
        while(!st.empty()) {
            TreeNode* cur = st.top();
            st.pop();
            res.push_back(cur->val);
            if (cur->right) {
                st.push(cur->right);
            }
            if (cur->left) {
                st.push(cur->left);
            }
        }
        return res;
    }
};

中序遍历

中序遍历是左根右,所以我们应该一路遍历到最左边,然后弹出栈,然后对弹出栈的元素访问它的右节点,这里有一个注意的点就是while()的条件,只有栈为空,并且这个结点也是空的,说明此时这个cur是在整个树的最右边且指向的是nullptr

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> res;
        TreeNode* cur = root;
        while(cur != nullptr || !st.empty()) {
            if (cur != nullptr) {
                st.push(cur);
                cur = cur->left;
            } else {
                cur = st.top();
                res.push_back(cur->val);
                st.pop();
                cur = cur->right;
            }
        }
        return res;
    }
};

后序遍历

后序遍历就是前序遍历改变一下顺序,前序遍历是中左右,如果我们调换一下入栈的顺序,变成中右左,在最后把结果反过来,也就变成了左右中了

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if (root == nullptr) {
            return {};
        }
        stack<TreeNode*> st;
        st.push(root);
        vector<int> res;
        while(!st.empty()) {
            TreeNode* cur = st.top();
            st.pop();
            res.push_back(cur->val);
            if (cur->left) {
                st.push(cur->left);
            }
            if (cur->right) {
                st.push(cur->right);
            }
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

二叉树的层序遍历

用队列来实现,如果要收集每一排的数据作为一个数组,那么我们需要一个size来记录每一个while()循环开始时队列的代码,然后这个size就是for()的结束标识,因为如果是que,size(),for()循环里面的每一次入队都会改变这个结果。

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        vector<vector<int>> res;
        if (root == nullptr) {
            return res;
        }
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            vector<int> path;
            for(int i = 0; i < size; i++) {
                TreeNode* cur = que.front();
                path.push_back(cur->val);
                que.pop();
                if (cur->left) {
                    que.push(cur->left);
                }
                if (cur->right) {
                    que.push(cur->right);
                }
            }
            res.push_back(path);
        }
        return res;
    }
};

总结

本篇文章就到这里结束了!!!希望可以帮助大家理解~~~