[ 二叉树 ] 二叉树遍历(递归+非递归)代码实现

二叉树遍历递归写法

  • 递归思想
  • 前序、中序、后序的定义

前序遍历

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        preorder(root, ans);
        return ans;
    }
    void preorder(TreeNode* root, vector<int>& ans) {
        if (!root) return;
        
        ans.emplace_back(root->val); 	// 中
        preorder(root->left, ans);		// 左
        preorder(root->right, ans);		// 右
    }  
};

中序遍历

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        inorder(root, ans);
        return ans;
    }
    void inorder(TreeNode* root, vector<int>& ans) {
        if (!root) return;
        
        inorder(root->left, ans);		// 左
        ans.emplace_back(root->val);	// 中
        inorder(root->right, ans);		// 右
    }
};

后序遍历

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        postorder(root, ans);
        return ans;
    }
    void postorder(TreeNode* root, vector<int>& ans) {
        if (!root) return;
        
        postorder(root->left, ans);		// 左
        postorder(root->right, ans);	// 右
        ans.emplace_back(root->val);	// 中
    }
};

二叉树遍历非递归写法

为了统一风格,采用标记法

  • DFS
  • 保存访问顺序
  • nullptr标记处理时机

中序遍历(详细注释)

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        // 返回值构造
        vector<int> ans;
        
        // 非递归 --> 辅助栈
        stack<TreeNode*> stk;
        
        // 非空检查
        if (root) stk.push(root);

        // 主干代码
        while (!stk.empty()) {
            // 访问栈顶结点 并弹出
            TreeNode* node = stk.top();
            stk.pop();

            // 如果是实际存在的结点
            if (node) {
                // 1. 压入相关结点, 由中序遍历, 我们按左中右逆序压栈
                if (node->right) stk.push(node->right);
                stk.push(node);

                // 2. 关键:访问但未处理中结点, 我们压入空指针作为标记
                stk.push(nullptr);
                if (node->left) stk.push(node->left);
            }
            // 如果是标记结点, 则意味着我们需要处理结点了
            else {
                node = stk.top();
                stk.pop();
                ans.emplace_back(node->val);
            }
        }
        return ans;
    }
};

前序遍历(变化点注释)

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> stk;
        if (root) stk.push(root);
        while (!stk.empty()) {
            TreeNode* node = stk.top();
            stk.pop();
            if (node) {
                // 与中序遍历的差别仅在 访问顺序以及处理标记
                
                // 中左右逆序
                if (node->right) stk.push(node->right);
                if (node->left) stk.push(node->left);
                stk.push(node);

                // 标记中点
                stk.push(nullptr);
            }
            else {
                node = stk.top();
                stk.pop();
                ans.emplace_back(node->val);
            }
        }
        return ans;
    }
};

后序遍历(变化点注释)

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> stk;
        if (root) stk.push(root);
        while (!stk.empty()) {
            TreeNode* node = stk.top();
            stk.pop();
            if (node) {
                // 与中序遍历的差别仅在 访问顺序以及处理标记
                
                // 左右中逆序
                stk.push(node);

                // 标记中点
                stk.push(nullptr);
                if (node->right) stk.push(node->right);
                if (node->left) stk.push(node->left); 
            }
            else {
                node = stk.top();
                stk.pop();
                ans.emplace_back(node->val);
            }
        }
        return ans;
    }
};

二叉树层序遍历(详细注释)

  • BFS
  • 队列保存访问顺序
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        // 返回值构造,原题目输出是二维的
        vector<vector<int>> ans;

        // BFS --> 辅助队列
        queue<TreeNode*> que;
        
        // 非空检查
        if (root != nullptr) {
            que.push(root);
        }

        // 主干代码
        while (!que.empty()) {
            // 1. 确定该层有多少结点
            int size = que.size();
            
            // 2. 保存该层处理的结点值
            vector<int> level;

            for (int i = 0; i < size; ++i) {
                // 3. 访问并处理结点
                TreeNode* node = que.front();
                que.pop();
                level.emplace_back(node->val);

                // 4. 保存下一层的结点
                if (node->left != nullptr) {
                    que.push(node->left);
                }
                if (node->right != nullptr) {
                    que.push(node->right);
                }
            }
            // 5. 保存该层结点处理结果
            ans.emplace_back(level);
        }
        return ans;
    }
};
  • 上一段代码返回值是按层输出,如果直接输出参考下列代码
class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        vector<int> ans;
        if (!root) return ans;
        queue<TreeNode*> que;
        que.push(root);
        while (!que.empty()) {
            TreeNode* node = que.front();
            que.pop();
            ans.emplace_back(node->val);
            if (node->left) que.push(node->left);
            if (node->right) que.push(node->right);
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值