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

1.二叉树前序遍历:

节点定义:

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

Leetcode144: https://leetcode.com/problems/binary-tree-preorder-traversal/

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

2.二叉树中序遍历:

Leetcode94: https://leetcode.com/problems/binary-tree-inorder-traversal/

基本思路:

1.将根节点压栈,并从该节点一直走到最左下(一直沿着左孩子走到左孩子非空的节点),途中依次将经过的节点压栈。

2.取栈顶节点,必定已访问过其左节点,输出val,并出栈;

3.若该节点有右孩子,则对右孩子做根节点一样的操作,即将右孩子压栈,并从该节点一直走到最左下(一直沿着左孩子走到左孩子非空的节点),途中依次将经过的节点压栈。

4.返回第2步,直至栈空。

class Solution
{
public:
    vector<int> inorderTraversal(TreeNode* root)
    {
        stack<TreeNode*> nodes;
        vector<int> res;
        if(root!=nullptr) //根节点非空
        {
            //将根节点压栈,并一直遍历到二叉树最左下
            nodes.push(root); 
            if(root->left!=nullptr)
            {
                TreeNode* left=root->left;
                while(left!=nullptr)
                {
                    nodes.push(left);
                    left=left->left;
                }
            }
        }
        while(!nodes.empty())
        {
            //对于出栈节点,已访问过其左孩子
            TreeNode* node=nodes.top();
            nodes.pop();
            res.push_back(node->val);
            //若该节点右孩子非空
            if(node->right!=nullptr)
            {
                //右孩子压栈
                TreeNode* right=node->right;
                nodes.push(right);
                //该节点左孩子非空,延该节点走到最左下
                if(right->left!=nullptr)
                {
                    TreeNode* left=right->left;
                    while(left!=nullptr)
                    {
                        nodes.push(left);
                        left=left->left;
                    }
                }
            }
        }
        return res;
    }
};

3.二叉树后序遍历:

Leetcode145: https://leetcode.com/problems/binary-tree-postorder-traversal/

后序遍历除了需要一个辅助栈,还需要给每一个栈中元素一个标记,标记这个节点是否已访问过其左节点和是否已访问过其左右节点。

基本思路:

1.若根节点非空,将其压栈。

2.取栈顶节点

a. 若标记visited==0,说明未访问过该节点的孩子;从该节点一直走到最左下(一直沿着左孩子走到左孩子非空的节点),途中依次将经过的节点压栈,并将压栈节点的标记都置为1(因为访问过其左孩子了)。

b. 若标记visited==1,说明访问过其左孩子,将其右孩子压栈,并将该节点标记置为2,从该节点一直走到最左下(一直沿着左孩子走到左孩子非空的节点),途中依次将经过的节点压栈,并将压栈节点的标记都置为1。

c. 若标记visited==2,说明访问过其左右孩子,则直接输出其val。

3.返回至第2步,直至栈空。

class Solution
{
public:
    vector<int> postorderTraversal(TreeNode* root)
    {
        vector<int> res;
        map<TreeNode*, int> visited;
        stack<TreeNode*> nodes;
        if(root!=nullptr)
            nodes.push(root);
        while(!nodes.empty())
        {
            TreeNode* node=nodes.top();
            if(visited.count(node))
            {
                if(visited[node]==2)
                {
                    //cout<<node->val<<endl;
                    res.push_back(node->val);
                    nodes.pop();
                }
                else ///visit right son
                {
                    visited[node]=2;
                    if(node->right!=nullptr)
                    {
                        TreeNode* right=node->right;
                        visited[right]=1;
                        nodes.push(right);
                        TreeNode* left=right->left;
                        while(left!=nullptr)
                        {
                            visited[left]=1;
                            nodes.push(left);
                            left=left->left;
                        }
                    }
                }
            }
            else
            {
                TreeNode* left=node->left;
                visited[node]=1;
                while(left!=nullptr)
                {
                    visited[left]=1;
                    nodes.push(left);
                    left=left->left;
                }
            }
        }
        return res;
    }
};
原文地址:https://www.cnblogs.com/jasonlixuetao/p/11149557.html