stl源码剖析 详细学习笔记 RB_tree (2)

//---------------------------15/03/22----------------------------

    

    //一直好奇KeyOfValue是什么,查了下就是一个和仿函数差不多的东西,在第7章会详细介绍

    //现在只知道KeyOfValue()可以构造一个类调用他的operator()可以得到一个valuekey

    

    //允许重复的插入

   template<class Key,class Value, class KeyOfValue,class Compare, class Alloc>

   typename rb_tree<key, Value, KeyOfValue, Compare, Alloc>::iterator

    rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v)

    {

        link_type y = header;

        link_type x = root();

        //从根节点开始搜索直到x为叶子节点

       while ( x != 0)

        {

            y = x;

            x = key_compare(KeyOfValue()(v),key(x)) ? left(x) : right(x);

        }

        

        //把一个值为v的节点插入x的位置,yx的父节点

       return __insert(x,y,v);

    }

    

    //不允许重复

    //可以插入(没有重复)返回的booltrue,否则为false

   template<class Key,class Value, class KeyOfValue,class Compare, class Alloc>

    pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator,bool>

    rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)

    {

        link_type y = header;

        link_type x =root();

       bool comp = true;

       while( x != 0)

        {

            y = x;

            comp = key_compare(KeyOfValue()(v),key(x));

            x = comp ? left(x) :right(x);

        }

        

        iterator j = iterator(y);

        

        //最后如果v "小于"(假设比较操作是小于) y

        //这边做这样的操作是因为"大于等于"的时候都会向右走,所以需要换一下j.nodev的位置

        //看看是否不相等

       if(comp)

           if(j == begin())    //如果插入点的父节点是最左边的节点

               return pair<iterator,bool>(__insert(x,y,v),true);

           else            //不是最左边就要--j继续判断

                --j;

        //这是因为只有最左边可以确定没有比v小的元素了

        

        //如果j.node确实小于v就可以插入。

       if(key_compare(key(j.node),KeyOfValue()(v)))

           return pair<iterator,bool>(__insert(x,y,v),true);

       return pair<iterator,bool>(j,false);

        

       /*

            总结下:会出现想等的情况只有有向右走的情况

            如果最后是向右走的,那么有可能相等的元素就是j也就是y也就是要插入位置 的父节点

            如果最后是向左走的,那么有可能相等的就是比j小的最大的那个元素,也就是--j

         

        */

    }

    

    

    //__insert

    

   template<class Key,class Value, class KeyOfValue,class Compare, class Alloc>

   typename    rb_tree<key, Value, KeyOfValue, Compare, Alloc>::iterator

    rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::

        __insert(base_ptr x_, base_ptr y_,const Value& v)

    {

        

        

        link_type x = (link_type) x_;

        link_type y = (link_type) y_;

        link_type z;

        

        //如果要插入的是根节点或者 要插入的位置不是空(header的左右儿子v小于那么就是要插入到左边

       if(y == header || x != 0 || key_compare(KeyOfValue()(v),key(y)))

        {

            z = create_node(v);

            left(y) = z;   //如果yheader那可以设置leftmostz

            //如果要插入的是根节点,

           if(y == header)

            {

               //设置根节点

                root() = z;

               //设置最右边的元素

                rightmost() = z;

            }

           //如果要插到最左边

           else if(y == leftmost())

                leftmost() = z;

            

        }

       else

        {

            z = create_node(v);

            right(y) = z;

           if (y == rightmost())

                rightmost() = z;

        }

        

        //父节点为y左右儿子都是 空。

        parent(z) = y;

        left(z) =0;

        right(z) =0;

        

       //调整平衡

        __rb_tree_rebalance(z,header->parent);

        ++node_count;

       return iterator(z);

    }

    

    

    //旋转以及变色

    

    

    //平衡这里inline是什么意思?里面明明有循环 而且代码这么长

    //下面的代码几乎和算法导论里的一样

    inline void

    __rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)

    {

        x->color = __rb_tree_red;

       while(x != root && x->parent->color == __rb_tree_red)

        {

           if(x->parent == x->parent->parent->left)

            {

                __rb_tree_node_base* y =x->parent->parent->right;

               if(y && y->color == __rb_tree_red)

                {

                    x->parent->color = __rb_tree_black;

                    y->color = __rb_tree_black;

                    x->parent->parent->color = __rb_tree_red;

                    x = x->parent->parent;

                }

               else

                {

                   if(x == x->parent->right)

                    {

                        x = x->parent;

                        __rb_tree_rotate_left(x, root);

                    }

                    x->parent->color = __rb_tree_black;

                    x->parent->parent->color = __rb_tree_red;

                    __rb_tree_rotate_right(x->parent->parent, root);

                }

            }

           else

            {

                __rb_tree_node_base* y =x->parent->parent->left;

               if(y && y->color == __rb_tree_red)

                {

                    x->parent->color = __rb_tree_black;

                    y->color = __rb_tree_black;

                    x->parent->parent->color = __rb_tree_red;

                    x = x->parent->parent;

                }

               else

                {

                   if(x == x->parent->left)

                    {

                        x = x->parent;

                        __rb_tree_rotate_right(x,root);

                    }

                    x->parent->color = __rb_tree_black;

                    x->parent->parent->color = __rb_tree_red;

                    __rb_tree_rotate_left(x->parent->parent,root);

                }

            }

        }

        root->color = __rb_tree_black;

    }

    

   //左转

    

   inline voide

    __rb_tree_rotate_left(__rb_tree_node_base* x,__rb_tree_node_base*& root)

    {

        __rb_tree_node_base* y = x->right;

        x->right = y->left;

       if(y->left != 0)

            y->left->parent = x;

        y->parent = x->parent;

        

       if(x == root)

            root = y;

       else if (x == x->parent->left)

            x->parent->left = y;

       else

            x->parent->right = y;

        y->left = x;

        y->parent = y;


    }

    

   //右转

   inline voide

    __rb_tree_rotate_right(__rb_tree_node_base* x,__rb_tree_node_base*& root)

    {

        __rb_tree_node_base* y = x->left;

        x->left = y->right;

       if(y->right != 0)

            y->right->parent = x;

        y->parent = x->parent;

        

       if(x == root)

            root = y;

       else if (x == x->parent->right)

            x->parent->right = y;

       else

            x->parent->left = y;

        y->right= x;

        y->parent = y;

        

    }

    

    //find

   template<class Key,class Value, class KeyOfValue,class Compare, class Alloc>

   typename    rb_tree<key, Value, KeyOfValue, Compare, Alloc>::iterator

    rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k)

    {

        link_type y =header;

        link_type x =root();

        

       while(x != 0)

           if(!key_compare(key(x), k))

                y = x, x =left(x);

       else

            x = right(x);

        

        iterator j =iterator(y);

       return (j ==end() || key_compare(k, key(j.node))) ? end() :j;

    }



    //最后没有delete操作,之前的算法导论部分已经给出了delete操作


posted @ 2015-03-22 20:31  boydfd  阅读(425)  评论(0编辑  收藏  举报