天天看点

二叉树的线索化及其前驱后继查找

一 实质

遍历二叉树过程中用线索(前驱和后继)取代空指针的的做法

二叉树的线索化及其前驱后继查找

主要是增加俩个指针,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

继续阅读