二叉树的遍历

一.迭代法

前、中、后序迭代法的统一写法:根节点先入栈,然后弹出栈中结点node的同时,将该结点node及其左右孩子按照当前遍历方式顺序的逆序存入栈中,并将该结点node存入栈后加入一个空节点作为标记。若下次弹出栈中元素为空节点标记(node==NULL),则处理该节点(visit);否则继续执行入栈操作。

以下是个人写的迭代法的统一版本,非统一版本可以看这篇文章:

408算法大题模板之二叉树篇 - 知乎 

二叉树的非递归遍历_RightJay的博客-CSDN博客_非递归遍历二叉树

1.前序遍历

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        vector<int> vec;
        stack<TreeNode*> stk;
        if(root!=NULL)
            stk.push(root);
        while(!stk.empty())
        {
            TreeNode* node = stk.top();
            stk.pop();//必须将该节点弹出,然后按遍历方式将各结点逆序存入栈中
            if(node!=NULL)
            {//注意栈的先进后出性,前序遍历顺序的逆序应为:右 左 中
                if(node->right)
                    stk.push(node->right);//右
                 if(node->left)
                    stk.push(node->left);//左
                stk.push(node);//中
                stk.push(NULL);//中节点访问过,但是还没有处理,加入空节点做为标记。
                //栈中有非空节点结点和空节点,遇到空节点则代表该节点需要处理,遇到非空节点则代表需要将该节点的左右孩子入栈.
            }
            else
            {
                vec.push_back(stk.top()->val);
                stk.pop();
            }
        }
        return vec;
    }
};

2.中序遍历

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) 
    {
        vector<int> vec;
        stack<TreeNode*> stk;
        if(root!=NULL)
            stk.push(root);
        while(!stk.empty())
        {
            TreeNode* node = stk.top();
            stk.pop();
            if(node!=NULL)
            {
                if(node->right)
                    stk.push(node->right);//右
                stk.push(node);//中
                stk.push(NULL);
                if(node->left)
                    stk.push(node->left);//左
            }
            else
            {
                vec.push_back(stk.top()->val);
                stk.pop();
            }
        }
        return vec;
    }
};

3.后序遍历

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        vector<int> vec;
        stack<TreeNode*> stk;
        if(root!=NULL)
            stk.push(root);
        while(!stk.empty())
        {
            TreeNode* node = stk.top();
            stk.pop();
            if(node!=NULL)
            {  
                stk.push(node);//中
                stk.push(NULL);
                if(node->right)
                    stk.push(node->right);//右
                if(node->left)
                    stk.push(node->left);//左
            }
            else
            {
                vec.push_back(stk.top()->val);
                stk.pop();
            }
        }
        return vec;
    }
};

4.层次遍历

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        vector<vector<int>> result;
        queue<TreeNode*> que;
        if(root!=NULL)
            que.push(root);
        while(!que.empty())
        {
            vector<int> vec;
            int size = que.size();//size即为该层的结点个数
            for(int i=0;i<size;i++)//注意这里必须用size,而不能用que.size(),因为que在不断变化.
            {
                TreeNode* node = que.front();
                que.pop();
                vec.push_back(node->val);
                if(node->left)
                    que.push(node->left);
                if(node->right)
                    que.push(node->right);
            }
            result.push_back(vec);
        }
        return result;
    }
};

二.递归法

有关递归问题的文章: 三道题套路解决递归问题 | lyl's blog

1.前序遍历

   void preorder(TreeNode* root,vector<int>& vec)
    {
        if(root==NULL)
            return;
        vec.push_back(root->val);
        preorder(root->left,vec);
        preorder(root->right,vec);
    }

2.中序遍历

    void inorder(TreeNode* root,vector<int>& vec)
    {
        if(root==NULL)
            return;
        inorder(root->left,vec);
        vec.push_back(root->val);
        inorder(root->right,vec);
    }

3.后序遍历

    void postorder(TreeNode* root,vector<int>& vec)
    {
        if(root==NULL)
            return;
        postorder(root->left,vec);
        postorder(root->right,vec);
        vec.push_back(root->val);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dorakmon0219

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值