• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            對于一般的二叉樹來說,刪去樹中的一個結點是沒有意義的,因為它將使以被刪除的結點為根的子樹變成森林,破壞了整棵樹的結構
            但是,對于二叉排序樹,刪去樹上的一個結點相當于刪去有序序列中的一個記錄,只要在刪除某個結點后不改變二叉排序樹的特性即可。
            ??????在二叉排序樹上刪除一個結點的算法如下:
            btree?*?DeleteBST(btree?*b,?ElemType?x)
            {
            ??????if?(b)
            ??????{
            ????????????if?(b->data?==?x)
            ??????????????????b?=?DelNode(b);
            ????????????else?if?(b->data?>?x)
            ??????????????????b->lchild?=?DeleteBST(b->lchild,?x);
            ????????????else
            ??????????????????b->rchild?=?DeleteBST(b->rchild,?x);
            ??????}
            ??????return?b;
            }
            其中刪除過程有兩種方法。
            第一種過程如下:
            1。若p有左子樹,找到其左子樹的最右邊的葉子結點r,用該葉子結點r來替代p,把r的左孩子
            作為r的父親的右孩子。
            2。若p沒有左子樹,直接用p的右孩子取代它。

            第二種過程如下:
            1。若p有左子樹,用p的左孩子取代它;找到其左子樹的最右邊的葉子結點r,把p的右子樹作為r
            的右子樹。
            2。若p沒有左子樹,直接用p的右孩子取代它。
            ????兩種方法各有優劣,第一種操作簡單一點點,但均衡性不如第二種,因為它將結點p的右子樹
            全部移到左邊來了。下面將分別以兩種種思路編寫代碼。


            第一種:
            btree?*?DelNode(btree?*p)
            {
            ??????if?(p->lchild)
            ??????{
            ????????????btree?*r?=?p->lchild;???//r指向其左子樹;
            ????????while(r->rchild?!=?NULL)//搜索左子樹的最右邊的葉子結點r
            ????????{
            ????????????r?=?r->rchild;
            ????????}
            ????????????r->rchild?=?p->rchild;

            ????????????btree?*q?=?p->lchild;???//q指向其左子樹;
            ????????????free(p);
            ????????????return?q;
            ??????}
            ??????else
            ??????{
            ????????????btree?*q?=?p->rchild;???//q指向其右子樹;
            ????????????free(p);
            ????????????return?q;
            ??????}
            }

            第二種:
            btree?*?DelNode(btree?*p)
            {
            ??????if?(p->lchild)
            ??????{
            ????????????btree?*r?=?p->lchild;???//r指向其左子樹;
            ????????????btree?*prer?=?p->lchild;???//prer指向其左子樹;
            ????????while(r->rchild?!=?NULL)//搜索左子樹的最右邊的葉子結點r
            ????????{
            ??????????????????prer?=?r;
            ????????????r?=?r->rchild;
            ????????}

            ????????if(prer?!=?r)//若r不是p的左孩子,把r的左孩子作為r的父親的右孩子
            ????????{
            ??????????????????prer->rchild?=?r->lchild;
            ??????????????????r->lchild?=?p->lchild;?//被刪結點p的左子樹作為r的左子樹
            ????????????}
            ????????r->rchild?=?p->rchild;?//被刪結點p的右子樹作為r的右子樹

            ????????????free(p);
            ????????????return?r;
            ??????}
            ??????else
            ??????{
            ????????????btree?*q?=?p->rchild;???//q指向其右子樹;
            ????????????free(p);
            ????????????return?q;
            ??????}
            }
            ????但是上面這種方法,把r移來移去,很容易出錯,其實在這里我們刪除的只是p的元素值,而不是它的地址,所以完全沒有必要移動指針。仔細觀察,發現我們刪除的地址實際上是p的左子樹的最右邊的葉子結點r的地址,所以我們只要把r的數據填到p中,然后把r刪除即可。
            算法如下:
            btree?*?DelNode(btree?*p)
            {
            ??????if?(p->lchild)
            ??????{
            ????????????btree?*r?=?p->lchild;???//r指向其左子樹;
            ????????????btree?*prer?=?p->lchild;???//prer指向其左子樹;
            ????????while(r->rchild?!=?NULL)//搜索左子樹的最右邊的葉子結點r
            ????????{
            ??????????????????prer?=?r;
            ????????????r?=?r->rchild;
            ????????}
            ????????????p->data?=?r->data;

            ????????if(prer?!=?r)//若r不是p的左孩子,把r的左孩子作為r的父親的右孩子
            ??????????????????prer->rchild?=?r->lchild;
            ????????????else
            ????????????p->lchild?=?r->lchild;?//否則結點p的左子樹指向r的左子樹

            ????????????free(r);
            ????????????return?p;
            ??????}
            ??????else
            ??????{
            ????????????btree?*q?=?p->rchild;???//q指向其右子樹;
            ????????????free(p);
            ????????????return?q;
            ??????}
            }
            Posted on 2006-06-04 16:52 夢想飛揚 閱讀(1967) 評論(2)  編輯 收藏 引用

            Feedback

            # re: 二叉排序樹的刪除  回復  更多評論   

            2006-10-23 17:11 by coolaway
            btree * DeleteBST(btree *b, ElemType x)
            {
            if (b)
            if (x< b->data)
            DeleteBST(b->lchild, x);
            else if (x> b->data)
            DeleteBST(b->rchild, x);
            else if(b->lchild != null && b->rchild != null)
            {
            btree *temp = Min(b->rchild); // find the min key value in right child
            DeleteBST(temp,temp->data);
            }
            else
            {
            if(b->rchild == null) b=b->lchild;
            else if(b->lchild == null) b=b->rchild;
            }

            }

            # re: 二叉排序樹的刪除  回復  更多評論   

            2007-10-15 12:48 by csuzl
            二叉排序樹刪除節點
            Status DeleteBST(BiTree &T, Keytype key,Bitree f) //引進f為T的父節點
            {
            if(!T) return FALSE;
            else
            {
            if(EQ(key,T->data.key))
            return Delete(T,f);
            else
            if(LT(key,T->data.key))
            {
            f = T;
            return DeleteBST(T->lchild,key,f);
            }

            else
            {
            f = T;
            return DeleteBST(T->rchile,key);
            }

            }
            }

            Status Delete(Bitree &p,Bitree f)
            {
            if(!p->rchild)
            {
            if(p==f->lchild)
            f->lchild = p->lchild;
            else
            f->rchild = p->rchild;
            free(p);
            }
            else if(!p->lchild)
            {
            if(f->lchild==p)
            f->lchild = p->rchild;
            else
            f->rchild = p->rchild;
            free(q);
            }
            else
            {
            BiTree q = p,s = p->rchild;
            while(s->lchild)
            {
            q = s;
            s = s->lchild; // 利用二叉排序樹的前驅后繼直觀圖幫助理解
            } //探索p的直接前驅,最后得到其為s(s->lchild==NULL).
            p->data = s->data; //覆蓋,容易理解
            if(q==p) // while未執行,有s=p->rchild,s覆蓋p,s位置由s->rchild占據.
            q->rchild = s->rchild;  
            else        //   未執行else前有,q->lchild=s;
            q->lchild = s->rchild; 
            free(s);
            }

            最后else部分亦可更改為:
            else //利用直接前驅s替代p
            {
            BiTree q = p,s = p->lchild;
            while(s->rchild)
            {
            q = s;
            s = s->rchild;
            } //探索p的直接前驅,最后得到其前驅為s(s->rchild==NULL).
            p->data =s->data;
            if(q==p)
            q->lchild = s->lchild;
            else
            q->rchild = s->lchild;
            free(s);
            }

            }

            777午夜精品久久av蜜臀| 欧美久久一级内射wwwwww.| 久久久久亚洲av综合波多野结衣| 漂亮人妻被中出中文字幕久久 | 亚洲中文精品久久久久久不卡| 伊人久久综合无码成人网| 国产亚洲欧美精品久久久| 国产综合精品久久亚洲| 久久久国产精华液| 久久综合九色综合久99| 国产精品一久久香蕉国产线看观看| 狠色狠色狠狠色综合久久| 久久久这里有精品中文字幕| 久久久久亚洲AV成人片| 亚洲国产精品嫩草影院久久| 大伊人青草狠狠久久| 久久久久久久波多野结衣高潮| 久久国产精品久久国产精品| 中文国产成人精品久久不卡| 久久久WWW成人免费精品| 久久精品国产福利国产秒| 久久精品中文字幕大胸| 99久久伊人精品综合观看| 色欲久久久天天天综合网精品| 久久天天躁狠狠躁夜夜2020老熟妇| 97热久久免费频精品99| A级毛片无码久久精品免费| 久久青青国产| 久久久久免费视频| 精品久久久久中文字| 亚洲一本综合久久| 99久久无色码中文字幕| 久久精品国产清高在天天线| 国产美女亚洲精品久久久综合| 亚洲伊人久久成综合人影院| 久久精品国产99久久久香蕉| 99久久亚洲综合精品成人| 亚洲一本综合久久| 久久国产成人午夜aⅴ影院| 久久久久免费视频| 久久精品国产亚洲AV香蕉|