• <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 閱讀(510) 評論(0)  編輯 收藏 引用 所屬分類: Notes on Introduction to Algorithms
            Google PageRank 
Checker - Page Rank Calculator
            精品无码久久久久国产| 久久久久国产精品麻豆AR影院| 久久亚洲电影| 中文字幕无码久久久| 亚洲伊人久久大香线蕉综合图片| 99精品久久精品一区二区| 国产精品免费福利久久| 久久亚洲精品无码播放| 久久天天躁狠狠躁夜夜不卡| 久久99国产精品久久99果冻传媒| 国产精品免费看久久久香蕉| 亚洲va久久久噜噜噜久久| 久久国产精品久久精品国产| 亚洲精品无码久久久| 久久久久综合网久久| 亚洲人成精品久久久久| 久久精品国产精品亚洲人人 | 亚洲精品无码久久久久sm| 91超碰碰碰碰久久久久久综合| 麻豆av久久av盛宴av| 狠狠人妻久久久久久综合蜜桃| 性欧美丰满熟妇XXXX性久久久| 日韩欧美亚洲国产精品字幕久久久| 久久亚洲美女精品国产精品| 久久中文字幕精品| 久久久WWW成人| 国内精品久久久久影院网站 | 欧美精品丝袜久久久中文字幕| 久久精品国产亚洲网站| 精品国产VA久久久久久久冰 | 午夜不卡888久久| 久久国产精品-国产精品| 无码久久精品国产亚洲Av影片| 欧美精品国产综合久久| 亚洲精品午夜国产va久久| 久久AAAA片一区二区| 久久成人18免费网站| 精品久久久久久国产牛牛app| 精品乱码久久久久久夜夜嗨| 秋霞久久国产精品电影院| 久久精品国产亚洲综合色|