1. 程式人生 > >二叉樹的遍歷和線索二叉樹

二叉樹的遍歷和線索二叉樹

二叉樹的遍歷和線索二叉樹

遞迴遍歷

先序遍歷

void PreOrder(BiTree T){
    if(T != NULL){
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T-rchild);
    }
}

中序遍歷

void InOrder(BiTree T){
    if(T != NULL){
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchild);
    }
}

後序遍歷

void PostOrder(BiTree T){
    if(T != NULL){
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    visit(T);
    }
}

非遞迴遍歷

先序遍歷非遞迴演算法

void PreOrderTraverse(BiTree T){
    InitStack(S);
    BiTree p=T;
        while(p||!IsEmpty(S)){           //棧不空或p不空時迴圈
        if(p){
            visit(p);
            Push(S,p);
            p=p->lchild;
        }
        else{
            Pop(S,p);
            p=p->rchild;
        }
    }
}

中序遍歷非遞迴演算法

void InOrderTraverse(BiTree T){
    InitStack(S);
    BiTree p=T;
    while(p||!IsEmpty(S)){
        if(p){
            Push(S,p);
            p=p->lchild;
        }
        else{
            Pop(S,p);
            visit(p);
            p=p->rchild;
        }
    }
}

後序遍歷非遞迴演算法

後序非遞迴遍歷二叉樹的順序是先訪問左子樹,再訪問右子樹,最後訪問根結點。

當用堆疊來儲存結點時,必須分清楚返回根結點時是從左子樹返回還是從右子樹返回的。
所以,使用輔助指標r,其指向最近訪問過的結點。也可在結點中增加一個標誌域,記錄是否已被訪問。

void PostOrder(BiTree T){
    InitStack(S);
    p=T;
    r=NULL;
    while(p||!IsEmpty(S)){
        if(p){
            Push(S,p);
            p=p->lchild;
        }
        else{
            GetTop(S,p);                     //注意不是出棧,是取棧頂元素
            if(p->rchild&&p->rchild!=r){     //若右子樹存在,且未被訪問過
                p=p->rchild;
                Push(S,p);
                p=p->lchild;
            }
            else{                            //右子樹已經訪問或為空,接下來出棧訪問結點
                Pop(S,p);
                visit(p->data);
                r=p;
                p=NULL;                     //使p為空,從而繼續訪問棧頂
            }
        }
    }
}