二叉树非递归

1、先序非递归

先序遍历:根->左->右

先序非递归最简单,使用栈保存节点。节点出栈后,直接访问(输出值或者保存下来),然后将右孩子加入栈,再将左孩子加入栈(注意左右的顺序)。

#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;

//* Definition for binary tree
struct TreeNode {
 int val;
 TreeNode *left;
 TreeNode *right;
 TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

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

int main(){
    TreeNode a(1), b(2), c(3), d(4), e(5);
    a.left = &b, a.right = &c, b.right = &d, b.left = &e;
    Solution s;
    vector<int> ans  = s.preorderTraversal(&a);
    for(int i = 0; i < ans.size(); i++)
        cout<<ans[i]<<" ";
    cout<<endl;
    return 0;
}

2、中序非递归

中序遍历:左->根->右

还是使用栈来存储节点,从当前节点一直往左孩子走,将左孩子加入栈中,如果左孩子为空了,则出栈访问这个元素,并进入右孩子节点,继续上面的流程。

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

3、后序非递归

后序遍历:左->右->根

还是使用栈保存节点,另外加一个pre指针指向上一个访问的节点。如果栈顶元素左右孩子都为空,那么可以访问它;或者pre是它的右孩子或左孩子(没有右孩子的时候才会出现pre是当前节点左孩子的情况),那么说明孩子节点都已访问完,也可以访问它。否则的话,不能访问栈顶节点,需要将它的右孩子和左孩子分别加入栈中。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        TreeNode *tmp, *pre = NULL;
        stack<TreeNode*> s;
        vector<int> ans;
        if(!root)return ans;
        s.push(root);
        while(!s.empty()){
            tmp = s.top();
            if(tmp->left==NULL && tmp->right==NULL || pre!=NULL && (pre==tmp->left||pre==tmp->right)){
                ans.push_back(tmp->val);
                s.pop();
                pre = tmp;
            }else{
                if(tmp->right) s.push(tmp->right);
                if(tmp->left) s.push(tmp->left);
            }
        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值