• <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>

            bon

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              46 Posts :: 0 Stories :: 12 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(2)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            今天實現了《算法導論》里提到的二叉搜索樹。
            支持的操作有:插入、刪除、查詢、前驅、后繼、遍歷等。
            首先定義樹節點的結構體:
            struct node{
                node(
            long k,int position){
                    l
            =r=p=NULL;
                    key
            =k,pos=position;
                }
                node(){
                    l
            =r=p=NULL;
                }
                node 
            *l,*r,*p;
                
            int pos;
                
            long key;
            };

            1. 插入操作
                
            void insert(long k,int position)
            {
                node 
            *yy=NULL;
                node 
            *xx = root;
                
            while(xx!=NULL){
                    yy
            =xx;
                    
            if(k>xx->key) xx=xx->r;
                    
            else xx=xx->l;
                }
                node 
            *z=new node(k,position);
                z
            ->p=yy;
                
            // 空樹
                if(yy==NULL) root=z;
                
            else{
                    
            if(yy->key<z->key) yy->r=z;
                    
            else yy->l=z;
                }
            }
            插入就是將新的鍵值放到合適的位置,使得二叉搜索樹的性質得以保存。
            用兩個指針yy,xx,yy指向xx的父節點。xx跟yy同時向下搜索:當待插入鍵值小于xx指向的節點鍵值時,xx指向xx的左兒子,否則指向右兒子。yy跟進。直到xx為空,說明到達合適的位置了,此時建立新的節點并把信息存進去。修改yy所指的節點(此時為新節點的父節點)的兒子指針。

            2. 刪除操作
            刪除操作比較復雜一些,先看下面的代碼:
             1 bool del(long key,node &res)
             2 {
             3     node *z=search(key);
             4     if(z==NULL) return false;
             5     
             6     node *y;
             7     if(z->==NULL || z->r==NULL) y=z;
             8     else y=successor(z->key);
             9     
            10     // x指向y的非空兒子,此時y最多只有一個兒子。若y無兒子,x為空
            11     node *x;
            12     if(y->l!=NULL) x=y->l;
            13     else x=y->r;
            14 
            15     // y有一個兒子,則將y刪去
            16     if(x!=NULL)    x->p=y->p;
            17     
            18     // y is the root
            19     if(y->p==NULL) root=x;
            20     else{
            21         if(y==y->p->l) (y->p)->l=x;
            22         else y->p->r=x;
            23     }
            24 
            25     // 當y!=z時,則y是z的后繼,刪去z后,y取代z
            26     if(y!=z) z->key=y->key,z->pos=y->pos;
            27     res.key=z->key,res.pos=z->pos;
            28     delete y;
            29     return true;
            30 }
            刪除鍵值為k的節點時,首先要找到這個節點,用函數node *search(long k),返回一個指針指向包含該鍵值的節點(如第3行所示)。
            接下來分三種情況:
            被刪節點無孩子、只有一個孩子、有兩個孩子。
            若是情況1或2,y指向被刪節點,否則指向被刪節點的后繼,如6~8行所示。這個操作后,y所指向的節點至多只有1個孩子(想想為什么)
            接著指針x指向y唯一的孩子(若有的話)并改變x的父親指針,指向y的父節點(注意此時y的父親指針仍指向y的父親)
            19~23行處理y是根的情況;26行處理case3的情況。
            最后刪除y,并以引用變量res返回被刪的節點的信息。
            3. 搜索
            包括找一個鍵值k,找鍵值k的前驅、后繼,最大最小值。
            原理比較簡單,代碼如下:
             1 // 返回以x為根的子樹的最小值
             2 node *minimum(node *x)
             3 {
             4     while(x->l!=NULL) x=x->l;
             5     return x;
             6 }
             7 
             8 node *maximum(node *x)
             9 {
            10     while(x->r!=NULL) x=x->r;
            11     return x;
            12 }
            13 
            14 // 返回x的后繼,即比x大的數中最小的一個
            15 node *successor(long k)
            16 {
            17     node *x=search(k);
            18     node *y=NULL;
            19     if(x->r!=NULL) return minimum(x->r);
            20     else{
            21         y=x->p;
            22         while(y!=NULL && x==y->r){
            23             x=y;
            24             y=x->p;
            25         }
            26     }
            27     // 若y==NULL 則x為根節點且無后繼
            28     return y;
            29 }
            30 
            31 node *predecessor(long k)
            32 {
            33     node *x=search(k);
            34     node *y=NULL;
            35     if(x->l!=NULL) return maximum(x->l);
            36     else{
            37         y=x->p;
            38         while(y!=NULL && x==y->l){
            39             x=y;
            40             y=x->p;
            41         }
            42     }
            43     return y;
            44 }
            4. 中序遍歷
               相當于是從小到大輸出樹中節點的鍵值。
            1 void inorderWalk(node *x)
            2 {
            3     if(x!=NULL){
            4         inorderWalk(x->l);
            5         printf("%d ",x->key);
            6         inorderWalk(x->r);
            7     }
            8 }

            posted on 2008-03-07 20:52 bon 閱讀(504) 評論(0)  編輯 收藏 引用 所屬分類: Notes on Introduction to Algorithms
            Google PageRank 
Checker - Page Rank Calculator
            久久久久亚洲AV无码观看| 91久久婷婷国产综合精品青草| 亚洲一区中文字幕久久| 成人a毛片久久免费播放| 国产精品亚洲美女久久久| 国产精品无码久久综合网| 久久综合亚洲鲁鲁五月天| 久久精品亚洲日本波多野结衣| 国产精品视频久久| 亚洲国产视频久久| 久久精品国产91久久综合麻豆自制| 精品久久综合1区2区3区激情 | 亚洲va久久久噜噜噜久久狠狠| 亚洲狠狠婷婷综合久久蜜芽| 99久久综合国产精品二区| 久久99久国产麻精品66| 精品国产一区二区三区久久蜜臀| 一本久久a久久精品亚洲| 精品久久久久久国产牛牛app| 色综合久久久久无码专区| 国产精品久久久久久久午夜片| 精品熟女少妇AV免费久久 | 久久久久九九精品影院| 午夜人妻久久久久久久久| 欧美久久一区二区三区| 国产一级持黄大片99久久| 亚洲va久久久噜噜噜久久狠狠| 久久综合给合综合久久| 91精品婷婷国产综合久久| 97久久精品人妻人人搡人人玩| 三级三级久久三级久久| 天天影视色香欲综合久久| 久久97久久97精品免视看| 久久91精品国产91久久小草| 久久久一本精品99久久精品66| 久久亚洲日韩看片无码| 99久久这里只精品国产免费| yy6080久久| 久久久无码人妻精品无码| 久久精品蜜芽亚洲国产AV| 青青草原精品99久久精品66|