二叉树遍历算法总结

二叉树遍历算法


前中后序遍历的教科书式写法
    //非递归前序遍历
    void preorderTraversal(TreeNode *root, vector<int> &path)
    {
        stack<TreeNode *> s;
        TreeNode *p = root;
        while(p != NULL || !s.empty())
        {
            while(p != NULL)
            {
                path.push_back(p->val);
                s.push(p);
                p = p->left;
            }
            if(!s.empty())
            {
                p = s.top();
                s.pop();
                p = p->right;
            }
        }
    }
    //非递归中序遍历
    void inorderTraversal(TreeNode *root, vector<int> &path)
    {
        stack<TreeNode *> s;
        TreeNode *p = root;
        while(p != NULL || !s.empty())
        {
            while(p != NULL)
            {
                s.push(p);
                p = p->left;
            }
            if(!s.empty())
            {
                p = s.top();
                path.push_back(p->val);
                s.pop();
                p = p->right;
            }
        }
    }
    //非递归后序遍历-迭代
    struct node{
        int data;
        node *left;
        node *right;
    };
    struct BTNode{
        node *btnode;
        bool isfirst;
    };
    void postorderTraverse(node *root)
    {
        stack<BTNode *> s;
        node *p = root;
        BTNode *temp;
        while (p != NULL || !s.empty())
        {
            while (p != NULL)
            {
                BTNode *btn = (BTNode *)malloc(sizeof(BTNode));
                btn->btnode = p;
                btn->isfirst = true;
                s.push(btn);
                p = p->left;
            }
            if (!s.empty())
            {
                temp = s.top();
                s.pop();
                if (temp->isfirst == true)
                {
                    temp->isfirst = false;
                    s.push(temp);
                    p = temp->btnode->right;
                }
                else
                {
                    cout << temp->btnode->data << " ";
                    p = NULL;
                }
            }
        }
    }
链接文章中给出了统一的的遍历解法

链接:http://zisong.me/post/suan-fa/geng-jian-dan-de-bian-li-er-cha-shu-de-fang-fa

前序遍历,中序遍历,后序遍历的通用解法(不太好理解,建议常规做法)

链接:https://leetcode.com/discuss/9736/accepted-code-with-explaination-does-anyone-have-better-idea
关于二叉树遍历地这段思想很好
There is an universal idea for preorder traversal inorder traversal and postorder traversal. For each node N, we process it as follows:
——- push N in stack -> push left tree of N in stack -> pop left tree of N -> push right tree of N in stack -> pop right tree of N -> pop N———
For preorder traversal, we visit a node when pushing it in stack. For inorder traversal, we visit a node when pushing its right child in stack.
For postorder traversal, we visit a node when popping it. lastpop represents the node which is popped the last time. For the top node in stack,
it has three choices, pushing its left child in stack, or pushing its right child in stack, or being popped. If lastpop != top->left, meaning that its left tree has not been pushed in stack, then we push its left child. If last_pop == top->left, we push its right child. Otherwise, we pop the top node.

void preorder_traversal_iteratively(TreeNode* root ) 
{
    if (root == 0 )
        return;
    stack<TreeNode *> s;
    s.push (root);
    cout << root ->val << ' ' ; // visit root
    TreeNode* last_pop = root;
    while (!s. empty())
    {
        TreeNode * top = s.top();
        if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
        {
            s .push( top->left );
            cout << top-> left->val << ' ' ; // visit top->left
        }
        else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
        {
            s .push( top->right );
            cout << top-> right->val << ' ' ; // visit top->right
        }
        else // pop
        {
            s .pop();
            last_pop = top;
        }
    }
}
void inorder_traversal_iteratively(TreeNode* root )
{
    if (root == 0 )
        return;
    stack<TreeNode *> s;
    s.push (root);
    TreeNode* last_pop = root;
    while (!s. empty())
    {
        TreeNode * top = s.top();
        if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
        {
            s .push( top->left );
        }
        else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
        {
            s .push( top->right );
            cout << top-> val << ' '; // visit top
        }
        else // pop
        {
            s .pop();
            last_pop = top;
            if ( top->right == 0 )
                cout << top-> val << ' '; // visit top
        }
    }
}
void postorder_traversal_iteratively(TreeNode* root )
{
    if (root == 0 )
        return;
    stack<TreeNode *> s;
    s.push (root);
    TreeNode* last_pop = root;
    while (!s. empty())
    {
        TreeNode * top = s.top();
        if ( top->left != 0 && top->left != last_pop && top->right != last_pop) // push_left
        {
            s .push( top->left );
        }
        else if (top->right != 0 && top->right != last_pop && (top ->left == 0 || top->left == last_pop)) // push_right
        {
            s .push( top->right );
        }
        else // pop
        {
            s .pop();
            last_pop = top;
            cout << top-> val << ' '; // visit top
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值