【LeetCode刷题日志】:二叉树的前序遍历和后序遍历

84 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

1、写在前面

大家好,这里是【LeetCode刷题日志】。今天的两道题分别是:

  • 二叉树的前序遍历
  • 二叉树的后序遍历

2、内容

2.1、题目一

链接:144. 二叉树的前序遍历 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

image.png

image.png

image.png

image.png

(3) 解题

1)递归

参考代码:

/**
 * 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:
    // 自定义递归函数
    void pretraversal(TreeNode* cur, vector<int>& v) {
        if (cur == NULL) return;
        v.push_back(cur->val);          // 中
        pretraversal(cur->left, v);     // 左
        pretraversal(cur->right, v);    // 右
    }
    // 调用函数,返回结果
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        pretraversal(root, result);
        return result;
    }
};

2)迭代

参考代码:

/**
 * 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) {
        vector<int> result;         // 定义一个vector容器变量,用于存放结果
        stack<TreeNode*> st;        // 定义一个工作栈
        if (root) st.push(root);    // 如果根结点不为空,则将其压入栈
        TreeNode* node;             // 定义一个工作结点
        // 当栈为空时,退出循环
        while (!st.empty()) {
            node = st.top();        // 将工作结点指向栈顶元素
            if (node != NULL) {
                st.pop();           // 将当前栈顶元素弹出
                if (node->right) st.push(node->right);  // 如果右子树不为空,则将右子树压入栈中
                if (node->left) st.push(node->left);    // 如果左子树不为空,则将左子树压入栈中        
                st.push(node);      // 将中结点压入栈中
                st.push(NULL);      // 压入空结点,为了标记未处理的中结点
            }
            // 如果栈顶元素为NULL
            // 则表示遇到标记的空结点了
            // 此时空结点的下一位结点就是应处理的结点
            else { 
                st.pop();                   // 先将栈顶的空结点弹出
                node = st.top();            // 再将工作结点指向新的栈顶结点
                result.push_back(node->val);// 将当前处理的结点的值存入结果中
                st.pop();                   // 最后弹出当前处理的结点
            }
        }
        return result;
    }
};

2.2、题目二

链接:145. 二叉树的后序遍历 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

image.png

image.png

(3) 解题

1)递归

参考代码:

/**
 * 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:
    void postTraversal(TreeNode* cur, vector<int>& v) {
        if(cur == NULL) return;
        postTraversal(cur->left, v);
        postTraversal(cur->right, v);
        v.push_back(cur->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        postTraversal(root, result);
        return result;
    }
};

2)迭代

参考代码:

/**
 * 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) {
        vector<int> result;         // 定义一个vector容器变量,用于存放结果
        stack<TreeNode*> st;        // 定义一个工作栈
        if (root) st.push(root);    // 如果根结点不为空,则将其压入栈
        TreeNode* node;             // 定义一个工作结点
        // 当栈为空时,退出循环
        while (!st.empty()) {
            node = st.top();        // 将工作结点指向栈顶元素
            if (node != NULL) {
                st.pop();           // 将当前栈顶元素弹出
                st.push(node);      // 将中结点压入栈中
                st.push(NULL);      // 压入空结点,为了标记未处理的中结点
                if (node->right) st.push(node->right);  // 如果右子树不为空,则将右子树压入栈中
                if (node->left) st.push(node->left);    // 如果左子树不为空,则将左子树压入栈中
            }
            // 如果栈顶元素为NULL
            // 则表示遇到标记的空结点了
            // 此时空结点的下一位结点就是应处理的结点
            else { 
                st.pop();                   // 先将栈顶的空结点弹出
                node = st.top();            // 再将工作结点指向新的栈顶结点
                result.push_back(node->val);// 将当前处理的结点的值存入结果中
                st.pop();                   // 最后弹出当前处理的结点
            }
        }
        return result;
    }
};

3、写在最后

好的,今天就先刷到这里。