zoukankan      html  css  js  c++  java
  • 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操作


  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983164.html
Copyright © 2011-2022 走看看