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

STL源码剖析——RB-Tree(红黑树) 前言 有关红黑树的zh 阅读详情

//

//  RB_tree_STL.cpp

//  笔记

//

//  Created by fam on 15/3/21.

//

//


#include "RB_tree_STL.h"


//---------------------------15/03/21----------------------------


RB_tree

{

   /*

        一个由上而下程序:

        为了避免父子节点皆为红色的情况持续向上层发展,形成处理时效上的瓶颈,可以从上向下处理,

        假设新增的节点为a,那就沿着a的路径,只要看到一个节点的两个子节点都是红色,就把这个节点改为红色

        其他两个子节点改成黑色。

    */

    

    

    //RB_tree的节点设计

    

   typedef bool __rb_tree_color_type;

   const __rb_tree_color_type __rb_tree_red = false; //红色为0

   const __rb_tree_color_type __rb_tree_black = true;

    

    

    //__rb_tree_node_base

   struct __rb_tree_node_base

    {

       typedef __rb_tree_color_type color_type;

       typedef __rb_tree_node_base* base_ptr;

        

        color_type color;

        base_ptr parent;

        base_ptr left;

        base_ptr right;

        

        //一直向左走,就会找到最小值

       static base_ptr minimum(base_ptr x)

        {

           while (x->left != 0)

                x=x->left;

           return x;

        }

        

       //一直向右走

       static base_ptr maximum(base_ptr x)

        {

           while (x->right != 0)

                x=x->right;

           return x;

        }

    };

    

    

    //__rb_tree_node

    

    template<class Value>

   struct __rb_tree_node : public __rb_tree_node_base

    {

       typedef __rb_tree_node<Value>* link_type;

        Value value_field;

    };

    //节点设计结束

    

   /*

        re_tree的迭代器

        re_tree的迭代器和slist的迭代器很相似,都是分成两层结构

        re_tree属于双向迭代器,但是不具备随机定位的能力

     

    */

    

    

    //__rb_tree_base_iterator

   struct __rb_tree_base_iterator

    {

       typedef __rb_tree_node_base::base_ptr  base_ptr;

       typedef bidirectional_iterator_tag iterator_category;

       typedef ptrdiff_t difference_type;

        base_ptr node;

        

       void increment()

        {

           if(node->right != 0)

            {

                node = node->right;

               while (node->left != 0)

                    node =node->left;

            }

            //只要node是他父节点的右儿子,他就比他父亲大,我们要找比node大的

           else

            {

                base_ptr y= node->parent;

               while(node == y->right)

                {

                    node = y;

                    y = y->parent;

                }

               if(node->right != y)//如果node是根节点,而且没有右儿子

                    node=y;

            }

        }

        

       void decrement()

        {

            //这个发生在node时header或者end()时

           if(node->color == __rb_tree_red &&

               node->parent->parent == node)

                node =node->right;

           else if(node->left !=0)

            {

                base_ptr y = node->left;

               while(y->right != 0)

                    y = y->right;

                node = y;

            }

           else

            {

                base_ptr y =node->parent;

               while(node == y->left)

                {

                    node = y;

                    y = y->parent;

                }

                node = y;

            }

        }

        

        //原文说increment有4种状况,其实只有三种,状况2并不是一种结果

   

        

    };

    

   template<class Value,class Ref,class Ptr>

   struct __rb_tree_iterator : public __rb_tree_base_iterator

    {

       typedef Value value_type;

       typedef Ref reference;

       typedef Ptr pointer;

       typedef __rb_tree_iterator<Value, Value&, Value*> iterator;

       typedef __rb_tree_iterator<Value,const Value&,const Value*> const_iterator;

       typedef __rb_tree_iterator<Value, Ref, Ptr> self;

        //经过多日的stl熏陶,感觉有些明白self和iterator的关系了,self是当前的节点本身(因为self用到的地方

        //很多,可以简化书写,iterator是一个类型属性供别人使用的。

       typedef __rb_tree_node<Value>* link_type;

        

       //构造函数

        __rb_tree_iterator(){}

        __rb_tree_iterator(link_type x) {node = x;}

        __rb_tree_iterator(const iterator& x) {node = it.node;}

        

        referenceoperator*() const {return link_type(node)->value_field;}

    #ifdef __SGI_STL_NO_ARROW_OPERATOR

        pointeroperator->() const {return &(operator*());}

    #endif

        

        

        //++ --操作

        self&operator++() {increment(); return *this;}

        

        self&operator++(){increment();return *this;}

        selfoperator++(int)

        {

            self tmp = *this;

            increment();

           return tmp;

        }

        self&operator--(){decrement();return *this;}

        selfoperator--(int)

        {

            self tmp = *this;

            decrement();

           return tmp;

        }

    }

    

    

    //class rb_tree


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

           class Alloc = alloc>

   class rb_tree

    {

    protected:

       typedef void* void_point;

       typedef __rb_tree_node_base* base_ptr;

       typedef __rb_tree_node<Value> rb_tree_node;

       typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;

       typedef __rb_tree_color_type color_type;

        

    public:

       typedef Key key_type;

       typedef Value value_type;

       typedef value_type* pointer;

       typedef const value_type* const_pointer;

       typedef value_type& reference;

       typedef const value_type& const_reference;

       typedef rb_tree_node* link_type;

       typedef size_t size_type;

       typedef ptrdiff_t difference_type;

        

    protected:

        //内存分配和释放

        link_type get_node()

        {

           return rb_tree_node_allocator::allocate();

        }

       void put_node(link_type p)

        {

            rb_tree_node_allocator::deallocate(p);

        }

        

        //申请内存并调用构造函数等于new操作

        link_type create_node(const value_type& x)

        {

            link_type tmp = get_node();

            __STL_TRY

            {

                construct(&tmp->value_field,x);

            }

            

            __STL_UNWIND(put_node(tmp));

           return tmp;

        }

        

        //克隆一个节点,只有颜色和键值,不会拷贝关系(左右儿子) 有个疑问,为什么parent没有赋0

        link_type clone_node(link_type x)

        {

            link_type tmp = create_node(x->value_field);

            tmp->color = x->color;

            tmp->left =0;

            tmp->right =0;

           return temp;

        }

        

       void destroy_node(link_type p)

        {

            destroy(&p->value_field);

            put_node(p);

        }

        

        

    protected:

        

        size_type node_count;

        link_type header;

        Compare key_compare;

        

        link_type& root()const {return (link_type&) header->parent;}

        link_type& leftmost()const {return (link_type&) header->left;}

        link_type rightmost()const {return (link_type&) header->right;}

        

        

        //一下12个函数全部为了简化取成员操作

       static link_type& left(link_type x)

        {

           return (link_type&)(x->left);

        }

        

       static link_type& right(link_type x)

        {

           return (link_type&)(x->right);

        }

        

       static link_type& parent(link_type x)

        {

           return (link_type&)(x->parent);

        }

        

       static reference& value(link_type x)

        {

           return x->value_field;

        }

        

       static const Key& key(link_type x)

        {

           return KeyOfValue()( value(x));

        }

        

       static color_type& color(link_type x)

        {

           return (color_type&)(x->color);

        }

        

                    

       static link_type& left(base_ptr x)

        {

           return (link_type&)(x->left);

        }

        

       static link_type& right(base_ptr x)

        {

           return (link_type&)(x->right);

        }

        

       static link_type& parent(base_ptr x)

        {

           return (link_type&)(x->parent);

        }

        

       static reference& value(base_ptr x)

        {

           return ((link_type)x)->value_field;

        }

        

       static const Key& key(base_ptr x)

        {

           return KeyOfValue()( value(link_type(x)));

        }

        

       static color_type& color(base_ptr x)

        {

           return (color_type&)(link_type(x)->color);

        }

        

        //求最大和最小值

       static link_type minimum(link_type x)

        {

           return (link_type) __rb_tree_node_base::minimum(x);

        }

        

       static link_type maximum(link_type x)

        {

           return (link_type) __rb_tree_node_base::maximum(x);

        }

        

        

    public:

       typedef __rb_tree_iterator<value_type, reference, pointer> iterator;

        

    private:

        iterator __insert(base_ptr x, base_ptr y,const value_type& v);

        link_type __copy(link_type x, link_type p);

       void __erase(link_type x);

        //初始化,给header申请一个节点的内存,让root(header->parent)为0,让左右最值都为header,并设置成红色

       void init()

        {

            header = get_node();

            color(header) = __rb_tree_red;

            

            root() =0;

            leftmost() = header;

            rightmost() =header;

        }

        

        

    public:

        rb_tree(const Compare& comp=Compare()

                : node_count(0), key_compare(comp))

        {

                    init();

        }

        

        ~rb_tree()

        {

            clear();

            put_node(header);

        }

        

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

       operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);

        

    public:

       //各种基础操作

        Compare key_comp()const {return key_compare;}

        iterator begin() {return leftmost();}

        iterator end() {return header;}

       bool empty() const {return node_count ==0;}

        size_type size()const {return node_count;}

        size_type max_size()const {return size_type(-1);}

        

    public:

        

        pair<iterator,bool> insert_unique(const value_type& x);

        

        

        

    };


《STL源码剖析》之RB-tree AVL树之外,另一个被广泛运用的平衡二叉搜索树是RB-tree。所谓红黑树,不仅是一个二叉搜索树,它还满足以下性质: 性质1. 每个节点是红色或黑色; 性质2. 根是黑色; 性质3. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点) 性质4. 从任一节点到NULL(树尾端)的任何路径都包含相同数目的黑色节点。 阅读详情

相关推荐

STL源码剖析(十三)关联式容器之rb_tree

STL源码剖析(十三)关联式容器之rb_tree 文章目录STL源码剖析(十三)关联式容器之rb_tree一、rb_tree的数据结构二、rb_tree的迭代器三、rb_tree的操作3.1 构造函数3.2 析构函数3.3 插入元素3.4 删除元素3.5 其他操作 rt_tree是红黑树,在STL中,它并没有对使用者开放,但它非常重要,它作为set和map的底部支持 这篇文章不详细讨论红黑树的算法...

JT同学的博客 737

C++ STL源码学习(之RB Tree篇)

STL中很高效,也很复杂的一个数据结构

alpaca.blog 2129

【机器学习(一)】从零到一:用sklearn构建你的第一个机器学习项目

本文为机器学习新手提供了一个完整的端到端实战指南。通过使用Python的scikit-learn库,以经典的鸢尾花数据集为例,详细演示了从环境搭建、数据探索、预处理、模型训练与评估,到超参数调优和模型保存的全流程。文章旨在帮助读者快速构建第一个机器学习项目,掌握核心工作流和工程实践。

weixin_29070861的博客 467

STL之rb-tree和set

参考https://en.wikipedia.org/wiki/Red%E2%80%93black_tree ared–black treeis a kind ofself-balancing binary search tree. Each node stores an extra bit representing color, used to ensure that the tree remains approximately balanced during insertions and d...

starscream_wyz的博客 218

多模态特征融合方法总结

由于本人的研究是文本、语音和图像三者模态数据的融合,所以针对的是这三种模态的特征融合方法进行总结。 首先,多模态特征融合的方法大体分为三种

华辰烟雨的博客 9万+

Argoverse轨迹预测实战:从数据加载到地图API应用全解析

本文详细解析了Argoverse数据集在轨迹预测中的应用,从数据加载到地图API的实战技巧全涵盖。通过具体代码示例展示如何高效处理轨迹数据、实现可视化及基础预测模型,帮助开发者快速掌握自动驾驶轨迹预测的核心技术。特别介绍了Argoverse地图API的深度应用和性能优化经验。

weixin_29182481的博客 241

没事刷刷题——包含min函数的栈

实现一个能快速找出最小元素的栈结构,过程中踩了set的坑,查看并记录了下STL中set的erase实现逻辑。

书影 522

BLE透传速率调优(二)

摘要:本文分析了蓝牙协议中MDbit=1时应连续发送多包但实际只发一包的问题。通过波形分析和代码调试,发现问题的根源在于接收端出现sync error导致提前关闭接收窗口,而非发送端问题。最终通过调整RF时序参数(将rxpathdly改为13us)解决了TX到RX转换的同步问题,使连接事件能正常发送多个数据包,传输速率提升至70kb/s。文中详细记录了使用逻辑分析仪和trace宏调试的过程,揭示了CEVA芯片设计中TX中断与ACK接收的关联特性。

袁赟的博客 799

C++学习23:容器深度探索之RB-tree(红黑树)源码剖析

关联容器:非常有用,元素的查找和插入都是非常快的,可以看作一个小型数据库。 1 红黑树 红黑树是一种平衡二分搜索树。所谓平衡,是指没有一条过长的树枝,保持适度的平衡,这样有利于查找和插入; 红黑树提供遍历的功能,存在迭代器,可以++。如果遍历,会得到一个排序的状态(中序遍历)。 由于上述排序规则,所以不应该用红黑树的迭代器改变元素的值。也因为红黑树将用于后续set和map的底部支持,而且key是...

时间有泪 563

【Halcon 】Halcon 实战:如何为 XLD 模板添加极性信息以提升匹配精度?

本文介绍了Halcon中为XLD轮廓模板添加极性信息的实用技巧。通过先以"ignore_local_polarity"模式创建模板,首次匹配获得位置后,使用set_shape_model_metric运算符结合真实图像为模板注入极性信息(边缘明暗方向)。这种方法弥补了XLD模板初始不支持极性的缺陷,可显著提升后续匹配的精度和抗干扰能力。实验显示,添加极性信息后的模板匹配效果明显优于无极性的匹配结果。该技术特别适用于基于手动绘制或处理后的XLD轮廓创建模板的场景。

songhuangong123的博客 751

Loki 分布式日志中心服务

分布式日志中心 Loki + Promtail + Grafana

原名又逢乱世。不要放下学习的脚步,毕竟比天天打牌、钓鱼、打游戏更能从内在充实自己。 2354

C++ STL :红黑树rb_tree源码剖析

STL关联式容器map、set、multimap、multiset,绝大部分操作如插入、修改、删除、搜索,都是由其内含的红黑树来完成的。我下面会总结 STL中rb_tree怎么实现的。首先,rb_tree是红黑树,所以需要定义红色和黑色。然后需要定义 红黑树的节点。_Rb_tree_node_base定义了红黑树的节点类,从类中可以看出一个节点有颜色、父指针、左孩子指针、右孩子指针4个属性。然后定义了几个函数,可以找到以这个节点为根节点的红黑树的最大节点和最小节点。

_ 1648

【DEIM创新改进】全网首发、独家特征融合创新改进篇 | CVPR2025 | 引入RLAB残差线性注意力特征融合块,有效融合并强调多尺度特征,有效减少信息丢失,助力DEIM目标检测有效涨点

本文提出了一种改进DEIM网络模型的新方法RLAB(残差线性注意力特征融合模块),用于医学图像生物标志物分割。RLAB模块通过多尺度残差精炼和注意力机制,有效整合编码器跳跃连接与解码器特征图,提升特征对齐和关键区域关注能力。实验表明,该方法在MoNuSeg、DSB等四个医学图像数据集上显著优于现有方法,最高提升4.03%的绝对性能。文章详细介绍了RLAB的网络结构、核心代码实现方式,并提供了将模块集成到DEIM模型的具体步骤。

Ai缝合怪、助力小伙伴高效发论文 349

STL源码剖析笔记——AVL-tree、RB-tree、set、map、mutiset、mutimap

STL源码剖析笔记——AVL-tree、RB-tree、set、map、mutiset、mutimap

weixin_48956191的博客 1136

luks-磁盘加密工具

linux磁盘加密配置工具及步骤详解

zdd56789的博客 120

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

STL源码剖析——关联容器之map

前言

关注校招求职,微信号:job_campus 3644

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

STL源码剖析——RB_TREE

花了差不多一个星期的时间读完了STL红黑树的实现,并凭理解自己写了出来 参考了《算法导论》,教你透彻了解红黑树,强烈推荐,《STL源码剖析》 记录下自己的理解RB_TREE红黑树优点: 与BST相比插入,查找,删除在最坏情况下的复杂度仍为O(lgn),相比BST应用范围更广 STL容器set,map都以红黑树为底层容器实现,Linux进程调度算法也用红黑树实现四种性质: 1. 每个结点要

ProgrammingLearner的博客 511

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C++ STL源码剖析 10-rb_tree

Red-Black Tree 红黑树

wesigj的博客 2018

源码剖析:STL中红黑树(RB-tree)

本文深入解析红黑树(RB-tree)的实现原理与数据结构设计。首先介绍红黑树的五大规则:根黑、不红红、黑路同等特性,并分析了插入节点时的三种情况(根节点、红叔叔、黑叔叔)及对应的旋转操作。对删除操作也分情况讨论,包括单子节点和无子节点场景。详细阐述了红黑树的节点结构设计、迭代器实现(双向迭代器),以及底层数据结构成员定义。最后探讨了红黑树的构造方式(空树/复制)和关键操作:insert_unique(不重复插入)、insert_equal(允许重复)和find查找方法

WildPointer的博客 1144

STL源码剖析 - RB-tree

在我看来,看源码是一件既痛苦又兴奋的事。当我们在推敲其中的难点时,是及其痛苦的,但当发现实现代码是那么丝滑简洁时,“wc, nb!”。 1. 导语 如果我们去看关联式容器map、set、multimap、multiset源代码,我们发现绝大部分操作如插入、修改、删除、搜索,均是由其内含的红黑树来完成的,我们有必要去揭开她的神秘面纱,一览她的绝世风姿。 (如果你手头还没有《STL源码剖析》...

yocichen 194

STL源码分析之RB-tree结构简析

所谓关联容器:          每笔数据(每个元素)都有一个键值(key)和一个实值(value)。当元素被插入到关联式容器中时,容器内部结构(可能是RB-Tree 也可能是hash-table)便依照其键值大小,以某种特定规则将这个元素置放于适当的位置。          关联容器没有所谓的头尾(只有最大元素和最小元素),所以不会有所谓的push_back(), push_front(),

博客 795

【红黑树进阶】手撕STL源码:从零封装RB-tree实现map和set

本文深入剖析STL底层设计思想,带你手把手将红黑树封装成自己的map和set。核心内容包括:KeyOfT仿函数解决比较问题、迭代器的完整实现(++/--操作)、map的operator[]重载、const迭代器与const正确性保证。通过完整的代码实现(RBTree.h/Myset.h/Mymap.h),让你彻底理解STL中map/set的复用机制。适合有一定红黑树基础,想深入掌握STL源码精髓的开发者,建议结合源码学习!

燃于AC之乐的博客 879

续 "关于sgi stl为什么使用rb-tree的想法"

这两天继续研究RB_Tree。上次说到为什么sgi stl会选择rb_tree作为set,map的基础实现,而不选择avl_tree。经过对资料的查询,最终,得出的结论是rb_tree在rebalance方面右性能优势。rb_tree的rebalance的时间顶多是进行两次totate,而avl_tree就需要有O(log(N))的时间。那么,这次我们先来研究为什么rb...

a848354317的博客 175

STL源码剖析 - 第5章 关联式容器 - RB-tree(红黑树)

5.1 树的导览      标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和multimap(多键映射表)。这些容器的底层机制均以RB-tree(红黑树)完成。RB-tree也是一个独立的容器,但并不开放给外界使用。 此外,SGI STL还提供了一个不在标准规格之列的关联式容器:hash table(散列表),以及以此hash

灯火阑珊处 758
上一篇: 算法导论笔记 红黑树(3)
下一篇: stl源码剖析 详细学习笔记 RB_tree (2)
boydfd
博客等级 码龄16年 101粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值