颜色遍历法非递归遍历二叉树

二叉树的遍历主要有三种方法:前序遍历、中序遍历和后序遍历。这三种方法的非递归实现形式各有特点,较为复杂。然而,有一种通用的遍历方法——颜色标记法,可以应用于前序、中序、后序以及层次遍历。

之前笔试题遇到非递归遍历二叉树,平时都是递归写的,猝不及防的翻车了,在leetcode看见了这个方法,很神奇,基本都是100%击败,而且一套通用前序、中序、后序,学会了以后麻麻再也不用担心面试遇到写非递归遍历二叉树了,

学之前:各种奇怪的姿势利用栈模拟来遍历二叉树;
学之后:自信.jpg, 王之藐视.jpg,一套通杀!

一、方法解释

颜色标记法使用颜色来标识节点的状态。新访问的节点被标记为白色,已访问过的节点则为灰色。在遍历过程中,每当我们遇到一个白色节点,我们就将其标记为灰色,并将它和它的左右子节点依次压入栈中。如果遇到的节点是灰色的,则直接输出该节点的值。这种方法的优点在于其适用于各种类型的二叉树遍历,使得代码更加简洁并易于理解。

二、代码实现

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};


// 中序遍历
vector<int> inorderTraversal(TreeNode* root) {
    int white = 0, gray = 1;
    vector<int> res;
    vector<pair<int, TreeNode*>> stk;
    stk.push_back({white, root});
    while(!stk.empty()){
        auto [color, node] = stk.back();
        stk.pop_back();
        if(node == nullptr) continue;
        if(color == white){
            stk.push_back({white, node->right});
            stk.push_back({gray, node});
            stk.push_back({white, node->left});
        } else {
            res.push_back(node->val);
        }
    }
    return res;
}


// 前序遍历
vector<int> preorderTraversal(TreeNode* root) {
    int white = 0, gray = 1;
    vector<int> res;
    vector<pair<int, TreeNode*>> stk;
    stk.push_back({white, root});
    while(!stk.empty()){
        auto [color, node] = stk.back();
        stk.pop_back();
        if(node == nullptr) continue;
        if(color == white){  
            stk.push_back({white, node->right});
            stk.push_back({white, node->left});
            stk.push_back({gray, node});
        } else {
            res.push_back(node->val);
        }
    }
    return res;
}


// 后序遍历
vector<int> postorderTraversal(TreeNode* root) {
    int white = 0, gray = 1;
    vector<int> res;
    vector<pair<int, TreeNode*>> stk;
    stk.push_back({white, root});

    while(!stk.empty()){
        auto [color, node] = stk.back();
        stk.pop_back();
        if(node == nullptr) continue;
        if(color == white){
            stk.push_back({gray, node});
            stk.push_back({white, node->right});
            stk.push_back({white, node->left});
        } else {
            res.push_back(node->val);
        }
    }
    return res;
}

三、知识点练习

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

交封面图不杀,开始摇摆,耶~

颜色遍历法非递归遍历二叉树_第1张图片

你可能感兴趣的:(数据结构与算法,算法,数据结构,c++,开发语言,c语言)