1. 程式人生 > >樹的非遞迴遍歷

樹的非遞迴遍歷

 

前序非遞迴遍歷

void preOrder2(BinTree *root)     //非遞迴前序遍歷 
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->lchild;
        }
        
if(!s.empty()) { p=s.top(); s.pop(); p=p->rchild; } } }

 

中序非遞迴遍歷

void inOrder2(BinTree *root)      //非遞迴中序遍歷
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            s.push(p);
            p
=p->lchild; } if(!s.empty()) { p=s.top(); cout<<p->data<<" "; s.pop(); p=p->rchild; } } }

 

後序非遞迴遍歷

要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點P,先將其入棧。如果P不存在左孩子和右孩子,則可以直接訪問它;或者P存 在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將P的右孩子和左孩子依次入棧,這樣就保證了 每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。

void postOrder3(BinTree *root)     //非遞迴後序遍歷
{
    stack<BinTree*> s;
    BinTree *cur;                      //當前結點 
    BinTree *pre=NULL;                 //前一次訪問的結點 
    s.push(root);
    while(!s.empty())
    {
        cur=s.top();
        if((cur->lchild==NULL&&cur->rchild==NULL)||
           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
        {
            cout<<cur->data<<" ";  //如果當前結點沒有孩子結點或者孩子節點都已被訪問過 
              s.pop();
            pre=cur; 
        }
        else
        {
            if(cur->rchild!=NULL)
                s.push(cur->rchild);
            if(cur->lchild!=NULL)    
                s.push(cur->lchild);
        }
    }    
}