天天看點

二叉樹的線索化及其前驅後繼查找

一 實質

周遊二叉樹過程中用線索(前驅和後繼)取代空指針的的做法

二叉樹的線索化及其前驅後繼查找

主要是增加倆個指針,pre指針始終指向剛剛通路過的節點,p指針始終指向目前通路的節點其中,*pre是*p的前驅,*p是*pre的後繼

三 中序線索化算法:

二叉樹的線索化及其前驅後繼查找

//将二叉樹按中序線索化算法  

typedef enum   {link,thread} pointertag;//枚舉值分别為0,1  

typedef struct node  

{  

    datatype data;  

    pointertag ltag,rtag;   //左右标志  

    struct node *lchild ,*rchild;  

}binthrnode;//線索二叉樹節點類型  

typedef binthrnode *binthrtree;  

void inorderthreading(binthrtree p)  

{//将二叉樹p中序線索化  

    if(p)//p非空時,目前通路結點是*p  

    {  

        inorderthreading(p->lchild);//左子樹線索化  

        //建立正在通路節點的前驅結點之間的線索  

        t->ltag = (t->lchild)?link:thread;  

        t->rtag = (t->rchild)?link:thread;  

        if(pre)  

        {  

            if(pre->rtag==thread)  

                pre->rchild = p;  

            if(p->ltag==thread)  

                p->lchid = pre;  

        }  

        pre = p;  

        inorderthreading(t->rchild);//右子樹線索化  

    }  

}  

算法分析:和中序周遊一樣遞歸過程對每個節點僅做一次通路,是以對于n個節點的二叉樹算法複雜度為o(n)

四 前驅和後繼的查找

二叉樹的線索化及其前驅後繼查找

binthrnode *inordersuccessor(binthrnode *p)  

{//在中序線索樹查找*p的後繼  

    binthrnode *q;  

    if(p->rtag==thread)  

        return p->rchlid;//傳回其所指的後繼  

    else  

        q = p->rchild;//從*p的右孩子開始查找  

        while(q->ltag==link)  

            q = q->lchild;//左子樹為空,沿左鍊往下查找  

        return q;  

 binthrnode *inorderpre(binthrnode *p)  

      {//在中序線索樹中找結點*p的中序前趨,設p非空  

         binthrnode *q;  

        if (p->ltag==thread) //*p的左子樹為空  

               return p->lchild; //傳回左線索所指的中序前趨  

         else{  

               q=p->lchild; //從*p的左孩子開始查找  

               while (q->rtag==link)  

                    q=q->rchild; //右子樹為空時,沿右鍊往下查找  

               return q; //當q的右子樹為空時,它就是最右下結點  

             } //end if  

      }  

從上面可以看出,對與非線索二叉樹,查找其節點十分困難需要周遊,而線索二叉樹加入了前驅和後繼之後是這種查找變得簡單易行

轉載:http://blog.csdn.net/xsf50717/article/details/40106441

繼續閱讀