• <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>
            posts - 34,comments - 2,trackbacks - 0
            1、二叉搜索樹(shù)是二叉樹(shù)的一種,樹(shù)的每個(gè)結(jié)點(diǎn)含有一個(gè)數(shù)據(jù)項(xiàng),每個(gè)數(shù)據(jù)項(xiàng)有一個(gè)鍵值。結(jié)點(diǎn)的存儲(chǔ)位置是由鍵值的大小決定的,所以二叉搜索樹(shù)是關(guān)聯(lián)式容器。
            (1)、 若它的左子樹(shù)不空,則左子樹(shù)上所有結(jié)點(diǎn)的鍵值均小于它的根結(jié)點(diǎn)的鍵值;
            (2)、若它的右子樹(shù)不空,則右子樹(shù)上所有結(jié)點(diǎn)的鍵值均大于它的根結(jié)點(diǎn)的鍵值;
            (3)、它的左、右子樹(shù)也分別為二叉排序樹(shù)。
            注意:::二叉排序樹(shù)是一種動(dòng)態(tài)樹(shù)表,樹(shù)的結(jié)構(gòu)通常不是一次生成的。而是在查找的過(guò)程中,當(dāng)樹(shù)中不存在關(guān)鍵字等于給定值的節(jié)點(diǎn)時(shí)再進(jìn)行插入。新插入的結(jié)點(diǎn)一定是一個(gè)新添加的葉子結(jié)點(diǎn),并且是查找不成功時(shí)查找路徑上訪問(wèn)的最后一個(gè)結(jié)點(diǎn)的左孩子或右孩子結(jié)點(diǎn)。

            2、插入與查找算法:
            查找:
            (1)、若二叉排序樹(shù)非空,將給定值與根節(jié)點(diǎn)的關(guān)鍵字值比較,若相等,則查找成功;
            (2)、若不等,則當(dāng)根節(jié)點(diǎn)的關(guān)鍵字值大于給定值時(shí),到根的左子樹(shù)中進(jìn)行查找;
            (3)、否則到根的右子樹(shù)中進(jìn)行查找。若找到,則查找過(guò)程是走了一條從樹(shù)根到所找到節(jié)點(diǎn)的路徑;
            (4)、否則,查找過(guò)程終止于一棵空樹(shù)。
            //① 、普通查找,查找不成功返回NULL
            遞歸思想:
             BiTree SearchBST (BiTree *T,KeyType key)
            {
                //在根指針T所指二叉排序樹(shù)中遞歸地查找某關(guān)鍵字等于key的數(shù)據(jù)元素
                //若查找成功,則返回指向該數(shù)據(jù)元素結(jié)點(diǎn)的指針,否則返回空指針
                    if( (!T)||(key==T—>data.key))
                        return (T); //查找結(jié)束,此時(shí)T為NULL,或者為該結(jié)點(diǎn)
                    else if (key< T—>data.key)
                            return(SearchBST(T—>lchild,key)); //在左子樹(shù)中繼續(xù)查找
                            else
                            return(SearchBST(T —>rchild,key));// 在右子樹(shù)中繼續(xù)查找
                }//SearchBST

            非遞歸思想:
            BiTree SearchBST (BiTree *root,KeyType key)

               BiTree *p;
               if( root == NULL)return NULL;//查找結(jié)束,此時(shí)根為NULL,
               p = root;
               while(p!=NULL)
               { 
                    if(p ->key==Key)breat;
                   if( Key < p ->key) p =p ->lchild//在左子樹(shù)中繼續(xù)查找
                     else p = p ->rchild;//在右子樹(shù)中繼續(xù)查找
                }
               return p;
            }
            //② 、查找不成功,返回插入位置
                //在根指針T所指二叉排序樹(shù)中遞歸地查找其關(guān)鍵字等于key的數(shù)據(jù)元素,
                //若查找成功,則指針p指向該數(shù)據(jù)元素結(jié)點(diǎn),并返回TRUE,
                //否則指針p指向查找路徑上訪問(wèn)的最后一個(gè)結(jié)點(diǎn)并返回FALSE,
                //指針f指向T的雙親,其初始調(diào)用值為NULL

             BOOL SearchBST(BiTree *T,KeyType key,BiTree *f,BiTree &p)
            {
                    if(!T) {p=f;return FALSE;} //查找不成功
                    else if (key==T—>data.key) 
                        {p=T;return TRUE;} //查找成功
                       else if (key<T—>data.key) SearchBST(T—>lchild,key,T,p); //在左子樹(shù)中繼續(xù)查找
                                    else SearchBST(T—>rchild,key,T,p);//在右子樹(shù)中繼續(xù)查找
                }//SearchBST

            插入:
            (1)、首先執(zhí)行查找算法,找出被插結(jié)點(diǎn)的父親結(jié)點(diǎn)。沒(méi)找到則新建子結(jié)點(diǎn)
            (2)、判斷被插結(jié)點(diǎn)是其父親結(jié)點(diǎn)的左、右兒子。將被插結(jié)點(diǎn)作為葉子結(jié)點(diǎn)插入。
            (3)、若二叉樹(shù)為空。則首先單獨(dú)生成根結(jié)點(diǎn)

            基于BOOL SearchBST(BiTree *T,KeyType key,BiTree *f,BiTree &p)的插入算法
            相當(dāng)于新建子樹(shù)。
             //當(dāng)二叉排序樹(shù)T中不存在關(guān)鍵字等于e.key的數(shù)據(jù)元素時(shí),插入e并返回TRUE,否則返回FALSE
            Status Insert BST(BiTree &T,ElemType e)
            {
                        if(!SearchBST(T,e.key,NULL,p) ) //返回P為插入的結(jié)點(diǎn)點(diǎn)
                    { //先查找,不成功新建結(jié)點(diǎn)
                        s=(BiTree)malloc(sizeof(BiTNode));
                        s->data=e; s->lchild= s->rchild=NULL;
                        if (!p) T = s; //被插結(jié)點(diǎn)*s為新的根結(jié)點(diǎn) ,原樹(shù)為空
                        else if (e.key<p->data.key) p->lchild=s; //被插結(jié)點(diǎn)*s為左孩子
                                else p—>rchild=s //被插結(jié)點(diǎn)*s為右孩子
                        return TRUE;
                      }
                    else 
                  return FALSE; //樹(shù)中已有關(guān)鍵字相同的結(jié)點(diǎn),不再插入
                }// Insert BST

              void InsertBST(BSTree *Tptr,KeyType key)
                  {
            //若二叉排序樹(shù) *Tptr中沒(méi)有關(guān)鍵字為key,則插入,否則直接返回
                    BSTNode *f,*p=*TPtr; //p的初值指向根結(jié)點(diǎn)
                    while(p){ //查找插入位置
                      if(p->key==key) return;//樹(shù)中已有key,無(wú)須插入
                      f=p; //f保存當(dāng)前查找的結(jié)點(diǎn)
                      p=(key<p->key)?p->lchild:p->rchild;
                        //若key<p->key,則在左子樹(shù)中查找,否則在右子樹(shù)中查找
                     } //endwhile
                     //f為插入的結(jié)點(diǎn)
                    p=(BSTNode *)malloc(sizeof(BSTNode));
                    p->key=key; p->lchild=p->rchild=NULL; //生成新結(jié)點(diǎn)
                    if(*TPtr==NULL) //原樹(shù)為空
                       *Tptr=p; //新插入的結(jié)點(diǎn)為新的根
                    else //原樹(shù)非空時(shí)將新結(jié)點(diǎn)關(guān)p作為關(guān)f的左孩子或右孩子插入
                      if(key<f->key)
                        f->lchild=p;
                      else f->rchild=p;
                   } //InsertBST


            4、刪除算法
            ①刪除操作的一般步驟
            (1) 進(jìn)行查找
                 查找時(shí),令p指向當(dāng)前訪問(wèn)到的結(jié)點(diǎn),parent指向其雙親(其初值為NULL)。若樹(shù)中找不到被刪結(jié)點(diǎn)則返回,否則被刪結(jié)點(diǎn)是*p。
            (2) 刪去*p。
                 刪*p時(shí),應(yīng)將*p的子樹(shù)(若有)仍連接在樹(shù)上且保持BST性質(zhì)不變。按*p的孩子數(shù)目分三種情況進(jìn)行處理。

            ②刪除*p結(jié)點(diǎn)的三種情況
            (1)*p是葉子(即它的孩子數(shù)為0)
                 無(wú)須連接*p的子樹(shù),只需將*p的雙親*parent中指向*p的指針域置空即可。

            (2)*p只有一個(gè)孩子*child
                 只需將*child和*p的雙親直接連接后,即可刪去*p。
              注意:
                 *p既可能是*parent的左孩子也可能是其右孩子,而*child可能是*p的左孩子或右孩子,故共有4種狀態(tài)。
            (3)*p有兩個(gè)孩子
                 先令q=p,將被刪結(jié)點(diǎn)的地址保存在q中;然后找*q的中序后繼*p,并在查找過(guò)程中仍用parent記住*p的雙親位置。*q的中序后繼*p一定是*q的右子樹(shù)中最左下的結(jié)點(diǎn),它無(wú)左子樹(shù)。因此,可以將刪去*q的操作轉(zhuǎn)換為刪去的*p的操作,即在釋放結(jié)點(diǎn)*p之前將其數(shù)據(jù)復(fù)制到*q中,就相當(dāng)于刪去了*q。
            ③二叉排序樹(shù)刪除算法
            分析:
                 上述三種情況都能統(tǒng)一到情況(2),算法中只需針對(duì)情況(2)處理即可。
                 注意邊界條件:若parent為空,被刪結(jié)點(diǎn)*p是根,故刪去*p后,應(yīng)將child置為根。


            算法:刪除關(guān)鍵字為key的結(jié)點(diǎn)
            void DelBSTNode(BSTree *Tptr,KeyType key)
             {
            //在二叉排序樹(shù)*Tptr中刪去關(guān)鍵字為key的結(jié)點(diǎn)
              BSTNode *parent=NUll,*p=*Tptr,*q,*child;
              while(p)

                 //從根開(kāi)始查找關(guān)鍵字為key的待刪結(jié)點(diǎn)
                if(p->key==key) break;//已找到,跳出查找循環(huán)
                parent=p; //parent指向*p的雙親
                p=(key<p->key)?p->lchild:p->rchild; //在關(guān)p的左或右子樹(shù)中繼續(xù)找
             } 
            //注意:也可以使用基于BOOL SearchBST(BiTree *T,KeyType key,BiTree *f,BiTree &p)的查找算法
            //結(jié)果是  parent 記錄了要?jiǎng)h除結(jié)點(diǎn)的父結(jié)點(diǎn),p指向要?jiǎng)h除的結(jié)點(diǎn)

                  if(!p) return; //找不到被刪結(jié)點(diǎn)則返回
                 q=p; //q記住被刪結(jié)點(diǎn)*p
                 if(q->lchild && q->rchild) //*q的兩個(gè)孩子均非空,故找*q的中序后繼*p
                for(parent=q,p=q->rchild; p->lchild; parent=p,p=p=->lchild);
              //現(xiàn)在情況(3)已被轉(zhuǎn)換為情況(2),而情況(1)相當(dāng)于是情況(2)中child=NULL的狀況
                child=(p->lchild)?p->lchild:p->rchild;//若是情況(2),則child非空;否則child為空
                if(!parent) //*p的雙親為空,說(shuō)明*p為根,刪*p后應(yīng)修改根指針
                  *Tptr=child; //若是情況(1),則刪去*p后,樹(shù)為空;否則child變?yōu)楦?br />    else{ //*p不是根,將*p的孩子和*p的雙親進(jìn)行連接,*p從樹(shù)上被摘下
                  if(p==parent->lchild) //*p是雙親的左孩子
                    parent->lchild=child; //*child作為*parent的左孩子
                  else parent->rchild=child; //*child作為 parent的右孩子
                  if(p!=q) //是情況(3),需將*p的數(shù)據(jù)復(fù)制到*q
                    q->key=p->key; //若還有其它數(shù)據(jù)域亦需復(fù)制
                 } //endif
                free(p); /釋放*p占用的空間
              } //DelBSTNode
            給出三種情況的不同算法
            第一種:
            btree * DelNode(btree *p)
            {
                  if (p->lchild)
                  {
                        btree *r = p->lchild;   //r
            指向其左子樹(shù);
                    while(r->rchild != NULL)//
            搜索左子樹(shù)的最右邊的葉子結(jié)點(diǎn)r
                    {
                        r = r->rchild;
                    }
                        r->rchild = p->rchild;
                        btree *q = p->lchild;   //q
            指向其左子樹(shù);
                        free(p);
                        return q;
                  }
                  else
                  {
                        btree *q = p->rchild;   //q
            指向其右子樹(shù);
                        free(p);
                        return q;
                  }
            }
            第二種:
            btree * DelNode(btree *p)
            {
                  if (p->lchild)
                  {
                        btree *r = p->lchild;   //r
            指向其左子樹(shù);
                        btree *prer = p->lchild;   //prer
            指向其左子樹(shù);
                    while(r->rchild != NULL)//
            搜索左子樹(shù)的最右邊的葉子結(jié)點(diǎn)r
                    {
                              prer = r;
                        r = r->rchild;
                    }

                    if(prer != r)//
            r不是p的左孩子,把r的左孩子作為r的父親的右孩子
                    {
                              prer->rchild = r->lchild;
                              r->lchild = p->lchild; //
            被刪結(jié)點(diǎn)p的左子樹(shù)作為r的左子樹(shù)
                        }
                    r->rchild = p->rchild; //
            被刪結(jié)點(diǎn)p的右子樹(shù)作為r的右子樹(shù)

                        free(p);
                        return r;
                  }
                  else
                  {
                        btree *q = p->rchild;   //q
            指向其右子樹(shù);
                        free(p);
                        return q;
                  }
            }



            posted on 2011-10-03 10:07 Yu_ 閱讀(606) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 數(shù)據(jù)結(jié)構(gòu)
            久久久久免费看成人影片| 久久综合日本熟妇| 精品多毛少妇人妻AV免费久久| 91精品无码久久久久久五月天 | 久久精品国产精品亚洲| 一本色道久久88加勒比—综合| 久久青草国产精品一区| 色综合久久中文色婷婷| 青青草国产精品久久久久| 久久se精品一区二区| 青青青青久久精品国产| 精品国产综合区久久久久久 | 久久久无码精品午夜| 久久久久久噜噜精品免费直播 | 精品伊人久久久| 久久久久久久波多野结衣高潮 | 97久久久久人妻精品专区| 久久精品一区二区国产| 99久久国产综合精品网成人影院| 欧美激情精品久久久久| 亚洲欧美日韩精品久久亚洲区 | 精品国产青草久久久久福利| 色偷偷久久一区二区三区| 久久伊人精品青青草原高清| 久久涩综合| 日韩人妻无码精品久久免费一| 国产精品久久久久aaaa| 久久综合九色综合精品| 久久人人添人人爽添人人片牛牛 | 国产精品99精品久久免费| 久久国产香蕉视频| 午夜人妻久久久久久久久| 99久久精品九九亚洲精品| 久久精品桃花综合| 国产福利电影一区二区三区久久老子无码午夜伦不| 久久久久九国产精品| 97精品国产91久久久久久| 久久无码AV中文出轨人妻| 91久久九九无码成人网站| 99久久精品免费看国产一区二区三区| 精品精品国产自在久久高清|