二叉树的递归和非递归遍历

1.递归遍历:

struct node {
    int value;
    node* left;
    node* right;
};

void preOrder(node* root)
{
    if(root == NULL)
        return;
    visit(root);
    preOrder(root->left);
    preOrder(root->right);
}

2.非递归遍历:

先序:

void preOrderNonrecursive(node* root)
{
    stack<node* > s;
    s.push(root);
    while(!s.empty())
    {
        node* pnode = s.pop();
        visit(pnode);
        if(pnode->right) s.push(pnode.right);
        if(pnode->left) s.push(pnode.left);
    }
}

中序:

void inOrderNonrecursive(node* root)
{
    stack<node*> s;
    s.push(root);
    node* current = root;
    while(!s.empty() || current != NULL)
    {
        if(current != NULL)
        {
            s.push(current);
            current = current->left;
        }
        else
        {
            current = s.pop();
            s.visit(current);
            current = current->right;    
        }              
    }
}

后序:

后序的非递归实现最为复杂,这里有一个巧妙的方法:

后序的遍历原则为,左子树,右子树,根。可见根是最先遍历到,最后访问的元素。正好符合栈的特点。

所以方法是,遍历树的同时,将根节点压入栈,最后全部出栈,就是后序的遍历序列了。

void postOrderNonrecursive(node* root)
{
    stack<node*> sTraverse, sVisit;
    sTraverse.push(root);
    while(!sTraverse.empty())
    {
        node* pnode = sTraverse.pop();
        if(pnode->left) sTraverse.push(pnode->left);
        if(pnode->right) sTraverse.push(pnode->right);
        sVisit.push(pnode);
    }
    while(!sVisit.empty())
        sVisit.pop();
}

这里要注意进栈和出栈的顺序。对于sTraverse栈,进栈的顺序为根,左右,出栈顺序为根,右左,正好对应sVisit栈的进栈顺序,故sVisit的出栈顺序为左,右,根,正好为后序遍历的顺序。

posted on 2013-03-07 16:02  书上一缕香  阅读(243)  评论(0编辑  收藏  举报

导航