二叉树的非递归前序、中序、后序遍历小记

前序遍历:

先访问根节点,再访问左子树,再访问右子树。
该代码思路为:入栈根节点,(循环开始处)读栈顶节点,读完弹出,同时入栈该顶节点的右子树,入栈左子树,然后读栈顶节点(进入循环开始处),进入循环...
代码如下:

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

中序遍历:

先访问左子树,再访问根节点,再访问右子树。
该代码思路为:只让左子节点依次入栈,首先从root开始依次循环遍历左子节点入栈。然后进入主循环依次弹出并读取栈顶节点数据,同时每次读取完判断该节点是否存在右子树,存在则让右子树为新的根节点,再次进行从root开始依次循环遍历左子节点入栈...
代码如下:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> vec;
        stack<TreeNode*> sta;
        TreeNode* tmp=root;
        while(tmp){//左子节点依次入栈
            sta.push(tmp);
            tmp=tmp->left;
        }
        while(!sta.empty()){
            tmp=sta.top();
            sta.pop();
            vec.push_back(tmp->val);
            tmp=tmp->right;//将右节点赋值给tmp,然后将赋值后的tmp看做一个新的二叉树的根节点,然后如下循环进行左子节点依次入栈
            while(tmp){//
                sta.push(tmp);
                tmp=tmp->left;
            }
        }
        return vec;
    }
};

后序遍历:

先访问左子树,再访问右子树,再访问根节点。
以下代码思路参考自:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/a-li-mian-shi-ti-zhi-yong-zhan-qu-zuo-er-cha-shu-d/
该代码思路为:压入根节点,(循环体入口处)判断栈顶节点是否为空节点,如果为空,说明该节点的子节点已经被遍历处理完了,处理该节点;如果不为空,说明其子节点还未处理。然后压入nullptr空节点,目的是分割父节点与子节点的,然后对该父节点的右子树节点和左子树节点分别压入栈。然后回到循环体入口处,判断栈顶节点是否为空节点...
代码如下:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> vec;
        stack<TreeNode*> sta;
        if(root)sta.push(root);
        while(!sta.empty()){
            TreeNode* tmp=sta.top();
            if(nullptr==tmp){//判断该节点是否为空节点,如果为空,说明该节点的子节点已经被遍历处理完了,可以处理该父节点了
                sta.pop();
                vec.push_back(sta.top()->val);
                sta.pop();
                continue;
            }
            sta.push(nullptr);//这个nullptr就是用来分割父节点与子节点的
            if(tmp->right){//由于是先左节点后右节点,所以是逆序压入栈
                sta.push(tmp->right);
            }
            if(tmp->left){//left下面还有没有子节点了?不知道,所以明知不为nullptr也要回到循环体开头,让nullptr入栈,然后就可以判断left有没有叶子节点了
                sta.push(tmp->left);
            }
        } 
        return vec;
    }
};
posted @ 2021-09-22 15:50  一只小菜菜鸟  阅读(89)  评论(0)    收藏  举报