二叉树前序,中序,后序遍历大全

二叉树是数据结构的基础,递归的版本是十分简单而且简洁,但是非递归版本就相对比较复杂些。

1.前序非递归便利二叉树:

  前序比较简单,从根开始访问,并一直往左,同时将访问后节点的右子树入栈(如果存在的话),直到栈空。

void preorder(TreeNode* root)
{
    stack<TreeNode*> st;
    if (root == NULL) return ;
    st.push(root);
    while (!st.empty())
    {
        TreeNode* p = st.top();
        st.pop();
        while (p != NULL)
        {
            cout << p->value << endl;
            if (p->r != NULL)
                st.push(p->r);
            p = p->l;
        }
    }
}

2.中序非递归遍历二叉树:

    中序遍历即,不断往左走,同时入栈所有经过的元素,找到最左边的节点访问,然后将访问后节点的右子树,入栈。此处有一个小窍门,如果右子树不存在,实际上我们应该访问根,所以我们应该压入NULL,压入NULL的目的在于阻止遍历过程再往左走。

void inorder(TreeNode* root)
{
    stack<TreeNode*> st;
    if (root == NULL) return ;
    st.push(root);
    while (!st.empty()) 
    {
        while (st.top() != NULL)
            st.push(st.top()->l);
        st.pop();
        if (!st.empty())
        {
            TreeNode* x = st.top();
            cout << x->value << endl;
            st.pop();
            //if (x->r != NULL)
                st.push(x->r);
        }
    }
}

3.二叉树后序遍历非递归:

     后序比较复杂,很多书上面都没有列出来。后序便利需要用另外一个栈来保存当前节点的右子树是否已经访问。

void posttravel(TreeNode* root)
{
    stack<TreeNode*> st;
    stack<bool> right;
    if (root == NULL) return;
    st.push(root);
    right.push(false);
    while (!st.empty())
    {
        while (st.top() != NULL)
        {
            st.push(st.top()->l);
            right.push(false);
        }
        st.pop();
        right.pop();
        if (st.empty()) break;
        if (right.top() == false)
        {
            right.pop();
            right.push(true);
            st.push(st.top()->r);
            right.push(false);
            
        }
        else
        {
            TreeNode* x = st.top();
            cout <<x->value << endl;;
            st.pop();
            right.pop();
            right.push(false);
            st.push(NULL);
        }
    }
}

注意代码中故意压栈的NULL,它的作用在于阻止继续往左遍历,

posted @ 2012-12-30 16:05  David Luo  阅读(1264)  评论(0编辑  收藏  举报