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


  • 相关阅读:
    Excel长数字防止转换为科学计数法
    SVN迁移部署
    且行且珍惜
    功能的权衡——推荐功能做不做?
    渗透小白如何学编程
    Metasploit log命令技巧
    Metasploit 使用msfconsole帮助功能技巧
    Metasploit resource命令技巧
    Metasploit makerc命令技巧
    Metasploit irb命令使用技巧
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983164.html
Copyright © 2020-2023  润新知