C++ 基于红黑树RBTree的关联容器Map类

C++红黑树实现map与set的底层原理与实践 红黑树作为一种高效的自平衡二叉搜索树,是理解现代C++关联容器(map/set)底层实现的关键数据结构。其通过颜色标记和旋转操作维护近似平衡,相比AVL树在插入删除时具有更好的综合性能。从工程实践角度看,红黑树实现涉及模板元编程、迭代器设计模式、异常安全等核心技术,是检验C++开发者底层功力的试金石。本文以STL容器为参照,详细剖析红黑树节点的内存管理、插入删除的平衡维护、迭代器设计等核心问题,特别针对map的pair结构和set的键唯一性进行差异化实现。通过手动实现这些基础容器,开发者不仅能深入理解红黑树 阅读详情

这道题尽管只有一句话,我却花了整整5天的时间,查阅了大量资料,来实现这个Map。毫无疑问,这道题的难度要远远超出了上一节的基于Vector向量类实现的Map,也因此,这个基于自平衡二叉树数据结构的Map,运行效率也要高效许多。

注:这里,我并没有找到关于“斜树”的任何资料。我仔细查阅了一下维基百科上的平衡二叉树条目,这里的“斜树”,我认为应该是指AVL树。当然,AVL树也是一种非常流行的平衡二叉树结构,但我这里实现用的是红黑树(据说自从红黑树发明后,就不再使用AVL树了。因为红黑树效率更高。当然,这是有争议的)。

 

上一篇中的Map类非常低效,尤其在下标插入元素时,需要遍历Vector来查找元素是否已存在:

template<class K,class V> V& Map<K,V>::operator[](const K& k)
{
	for(iterator p=vec.begin();p!=vec.end();++p)
		if(p->first==k) return p->second;
	vec.push_back(Pair<const K,V>(k,V()));
	return vec.back().second;
}


这是因为,这个基于Vector的Map类的数据结构,在本质上是一个线性表。也就是说,Vector中的元素是线性排列的,是没有规律的。因此,在查找一个元素时,就必须一个一个地遍历这个线性表,效率就会非常低。正是因为这个原因,需要弃用Vector而改用二叉树这样的数据结构。因为二叉树是根据键的大小来进行左右分支的,因此查找元素时只要比较键的大小,寻找子分支即可。这样一来,查找的效率就会大大提高。与此同时,插入、删除元素的效率也因此而提高了。

那为什么要用红黑树或者斜树呢?

这是因为,二叉树,在最坏情况下,也会退化成为一个线性链表。如果说不断插入降序或升序的一串元素,例如1、2、3、4、5,这样,二叉树就只能有一个分支,也就是只能有一个右分支,而那个右分支仍然只能有一个右分支。这样,二叉树就退化成了一个线性链表,插入效率也会非常差。

自平衡二叉树是指,在插入元素时,二叉树会自动调整元素的位置,使树的两叉维持平衡。而红黑树和斜树,是这目前相对流行的自平衡二叉树实现。这里,我采用的就是红黑树这种数据结构。红黑树最普遍的用途就是用来实现关联数组。

红黑树遵守5个基本命题:

1. 节点是红色或黑色。

2. 根是黑色。

3. 所有叶子都是黑色(叶子是NIL节点)。

4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

注意到命题5,“从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点”,这一点就保证了,红黑树的树高由于每个分支上黑色结点数目一定而维持平衡。

在具体实现中,我把这个红黑树实现为一个MapNode子节点构成的链表。MapNode包含3个指针成员,left、right和parent。以及一个颜色成员,color(实现为枚举类型COLOR)。

这里要注意的是,在插入操作的实现中,基本的插入操作是与二叉树一样的。然而,由于在插入新元素后可能导致红黑树的性质丢失,树失去平衡,因此在普通的二叉树插入操作之后需要调用insert_fix_up()函数来修复红黑树的性质,维持树的左右平衡。还有,树的旋转只能修复元素的位置和树的平衡,红黑树本身的红黑性质是无法修复的。因此在旋转后还要调整结点的颜色。

红黑树的具体原理和详细的阅读资料在附录中有。

//RBTree_Map.h
#include <iostream>
template<class K,class V> class Map;
template<class K,class V> class MapNode{
	friend class Map<K,V>;
	enum COLOR{RED,BLACK};

	MapNode(COLOR c=RED,MapNode* p=0,MapNode* l=0,MapNode* r=0,
		    const K k=K(),V v=V()):
	    color(c),parent(p),left(l),right(r),key(k),val(v){}
	COLOR color;
	MapNode* parent;
	MapNode *left,*right;
	const K key;
	V val;
};
template<class K,class V> class Map{
public:
	Map():root(0){}
	V& operator[](const K&);
	void print() const{print(root);}
private:
	MapNode<K,V>* root;

	MapNode<K,V>* grandparent(MapNode<K,V>* p)
	    {return p->parent->parent;}
	MapNode<K,V>* uncle(MapNode<K,V>* p)
	    {return p->parent==grandparent(p)->left?
	                       grandparent(p)->right:grandparent(p)->left;}
	void rotate_left(MapNode<K,V>*);
	void rotate_right(MapNode<K,V>*);
	void insert_fix_up(MapNode<K,V>*);

	void print(MapNode<K,V>* p) const
	{
		if(!p) return;
		print(p->left);
		std::cout<<p->key<<"\t"
			     <<p->val<<std::endl;
		print(p->right);
	}
};
template<class K,class V>
V& Map<K,V>::operator[](const K& key)
{
	MapNode<K,V>* p=root;
	MapNode<K,V>* pp=0;
	while(p){
		pp=p;
		if(key<p->key)
			p=p->left;
		else if(key>p->key)
			p=p->right;
		else
			return p->val;
	}
	p=new MapNode<K,V>(MapNode<K,V>::RED,pp,0,0,key,V());
	if(!pp)
	    root=p;
    else if(key<pp->key)
        pp->left=p;
    else
        pp->right=p;
	insert_fix_up(p);
	return p->val;
}
template<class K,class V>
inline void Map<K,V>::rotate_left(MapNode<K,V>* p)
{
	MapNode<K,V>* pr=p->right;
	p->right=p->right->left;
	if(pr->left) pr->parent=p;
	pr->parent=p->parent;
	if(!p->parent)
		root=pr;
	else if(p==p->parent->left)
		p->parent->left=pr;
	else
		p->parent->right=pr;
	pr->left=p;
	p->parent=pr;
}
template<class K,class V>
inline void Map<K,V>::rotate_right(MapNode<K,V>* p)
{
	MapNode<K,V>* pl=p->left;
	p->left=p->left->right;
	if(pl->right) pl->right->parent=p;
	pl->parent=p->parent;
	if(!p->parent)
		root=pl;
	else if(p==p->parent->right)
		p->parent->right=pl;
	else
		p->parent->left=pl;
	pl->right=p;
	p->parent=pl;
}
template<class K,class V>
inline void Map<K,V>::insert_fix_up(MapNode<K,V>* p)
{
	if(!p->parent)
		p->color=MapNode<K,V>::BLACK;
	else if(p->parent->color==MapNode<K,V>::BLACK)
		return;
	else if(uncle(p)!=0&&uncle(p)->color==MapNode<K,V>::RED){
		p->parent->color=MapNode<K,V>::BLACK;
		uncle(p)->color=MapNode<K,V>::BLACK;
		grandparent(p)->color=MapNode<K,V>::RED;
		insert_fix_up(grandparent(p));
	}
	else if(p==p->parent->right&&p->parent==grandparent(p)->left){
	    rotate_left(p->parent);
		p=p->left;
	}else if(p==p->parent->left&&p->parent==grandparent(p)->right){
		rotate_right(p->parent);
		p=p->right;
	}
	else{
		p->parent->color=MapNode<K,V>::BLACK;
		grandparent(p)->color=MapNode<K,V>::RED;
		if(p==p->parent->left&&p->parent==grandparent(p)->left)
			rotate_right(grandparent(p));
		else
			rotate_left(grandparent(p));
	}
}


这里,由于红黑树本身相当复杂,我只实现了红黑树Map的插入操作(也就是下标操作符[])。然而,还是花了整整5天时间。删除操作要比插入操作更难。我并不想实现删除操作,一方面是因为我认为我已经理解了红黑树的原理,实现了树的左旋和右旋,并且正确地实现了插入操作。另一方面是我认为红黑树的插入操作并没有太多关于C++程序设计技术的展示(已经有点超出《C++程序设计语言》这本书的范畴了)。过多研究数据结构和算法的做法并不可取。相反,标准库的Map类已经提供了一个非常高效的实现。因此花大量时间在这样一道模板的习题上,有些不明智。

主程序就是简单地测试Map的插入操作:

#include "RBTree_Map.h"
int main()
{
	Map<int,std::string> m;
	m[1]="one";
    m[2]="two";
	m[0]="zero";
	m[3]="three";
	m[4]="four";
	m[5]="five";
	m[6]="six";
	m[10]="ten";
	m.print();
	return 0;
}

 

附录

阅读资料

维基百科:《红黑树》    http://zh.wikipedia.org/wiki/%e7%ba%a2%e9%bb%91%e6%a0%91

《教你透彻了解红黑树》 ——July    http://blog.youkuaiyun.com/v_july_v/article/details/6105630

《红黑树的C++完整源码》  ——July    http://blog.youkuaiyun.com/v_july_v/article/details/6105630

拓展阅读

Knuth,《计算机程序设计艺术》,Vol.1

通用红黑树(Tree-Map)容器纯C实现 纯C实现的通用红黑树容器不好找,于是自己琢磨着实现了一个。 算法部分直接剪裁自Linux内核中的rbtree 作者主要是在此基础上封装了一个通用的容器 里面含有 test例子 以及 benchmark基准测试 另外这个是Windows和Linux都可以用的 由于Linux内核的rbtree用了很多C99语法,笔者还得写了一些宏改造内核代码 Linux下的make是完整的 Windows下提供了VS08版的sln文件(只有test木有benchmark) 附带了一个C++里面的STL Map的benchmark 立即下载

相关推荐

避坑指南:RK3568双网口RMII模式DTS配置常见错误与调试技巧

本文详细解析了RK3568双网口RMII模式DTS配置中的常见错误与调试技巧,涵盖时钟配置、PHY识别、复位时序等关键问题。通过实战案例和系统化调试方法,帮助开发者快速解决百兆以太网连接不稳定、PHY识别失败等典型问题,提升开发效率。

weixin_42549037的博客 343

Java提高篇(二七)-----TreeMap

原文出自:http://cmsblogs.com/?p=1013。尊重作者的成果,转载请注明出处! 个人站点:http://cmsblogs.com------------------------------------------------------------------------------------------------------------...

weixin_30580943的博客 2212

深入解析EDID中Display Descriptor Block的配置技巧与实战应用

本文深入解析EDID中Display Descriptor Block的配置技巧与实战应用。通过剖析像素时钟、有效像素、消隐区与同步脉冲等核心参数,并结合1280x720@60Hz的实战配置案例,指导开发者如何正确为定制硬件或非标准显示器编写“身份证”,避免黑屏、分辨率异常等问题,确保显示设备完美点亮。

1a2s3d4f5g的博客 878

C++ - 使用RBTree来封装Set与Map

前面的文章中我们简单的实现了一个红黑树,实现了它的插入的功能,在本文中我们来对其进行修改并构建Set与Map。

weixin_45138295的博客 445

NLP实战:如何用CoNLL-2003数据集快速提升命名实体识别模型性能(附完整代码)

本文详细介绍了如何利用CoNLL-2003公开数据集,通过深度剖析数据特点、构建鲁棒的数据预处理流水线、选择合适的模型架构(如BERT-CRF)以及优化训练策略,来系统性地提升命名实体识别(NER)模型的性能。文章提供了完整的代码示例,并分享了处理数据不均衡、标签对齐等核心挑战的实战技巧,帮助读者从理论到实践全面掌握NER任务。

cola5的博客 494

ArcGIS实战:用栅格数据为偏远山区规划一条最省钱的公路(附完整数据与操作步骤)

本文详细介绍了如何利用ArcGIS进行栅格数据分析,为偏远山区规划一条最省钱的公路。通过DEM高程数据处理、成本权重设定和最佳路径计算,结合真实案例展示了从数据准备到工程方案转化的完整流程,帮助工程师在复杂地形中做出经济高效的路线决策。

weixin_32136203的博客 356

红黑树的实现

红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。 红黑树的五条性质:(特别重要) 1.节点是红色或黑色 2.根节点是黑色 3. 每个叶节点(NIL节点,空节点)是黑色的,又称为外节点 4.如果一个节点是红色的,则他的两个子节点都是黑色的 5.对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的

tunyue456的专栏 446

DRAM内存模拟持久化设备的方法

由于持久化内存介质NVM技术的发展,越来越多的科研工作者投身到NVM相关的研究当中。但由于目前工业界并没有推出广泛使用的NVM介质设备,所以科研工作都需要自己以现有的条件,模拟NVM设备使用场景。一个简单的方法是:通过修改DRAM模拟器,达到模拟NVM的目的(可以参考:DRAMSim2模拟器分析与应用)。更高端的方式是:在真实系统中,将内存划分出一块儿,用来模拟NVM设备(类似于传统的ramdis

酷炫人笨笨熊 1899

Map容器家族(TreeMap源码详解)

一、在Map集合家族的位置及概述         TreeMap是一个有序的key-value集合,它内部是通过红-黑树实现的。TreeMap继承与AbstractMap,实现了NavigableMap接口,意味着它支持一系列的导航方法,比如返回有序的key集合。它还实现了Cloneable接口,意味着它能被克隆。另外也实现了Serializable接口,表示它支持序列化。TreeMap是基...

IdealSpring的博客 439

软硬件协同设计的大小端问题

缘起 最近需要在soc系统内做协处理器,加速AES加密运算,寄存器一次读取32bit,AES一次处理128bit,因此在数据拼接的时候,需要考虑大小端的问题,特来记录一番。 一、什么是大小端 大小端的问题发生在寄存器和内存间传递数据,这点非常重要,很多地方简单地说是数据存储方式,其实不准确。追根溯源,大小端问题是在设计load,store指令的时候考虑的,因此本质是寄存器和内存交互的问题,其他地方不会发生。 比如c语言里定义一个变量int a=ox1234,那么查看在线汇编平台的对应汇编代码: # 给2号寄

http://www.icfgblog.com/ 613

uniapp [安卓苹果App端] - 实现集成微信一键登录及授权获取用户信息全流程源码,uniApp唤起微信客户端app实现微信授权头像昵称手机号(提供移动应用/开放平台/资质认证/签名/权限申请

uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果安卓app,微信一键登录,uniapp项目App端实现微信登录,Uniapp实现微信授权登录,调起微信客户端授权用户信息,uniappapp端微信一键登录打开手机微信app,app端如何唤起用户本机微信应用并授权登陆,如何申请微信一键登录,uniapp实现APP微信登录流程,打开本地微信软件,接入微信登录,UniApp实现微信登录教程,获取头像昵称手机号用户数据,超详细实现微信登录功能,唤起没反应,授权失败,获取

🏆 前端领域优质创作者 1万+

终于搞懂红黑树!--红黑树的原理及操作

红-黑-树 介绍: 红黑树( Red black tree)是种自平衡二叉查找树,在计算机科学中用到的一种数据结构。 它是在1972年由 Rudolf Bayer发明的当时被称为平衡二叉B树( symmetric binary B-trees)。后来,在1978年被 Leo. guibas和 Robert sedgewick修改为如今的红黑树R-B Tree,全称是Red- Blac...

lzzw的学习之路 1万+

单智能体篇:Prompt工程艺术

模型在接收到 Prompt 时会自动扮演“角色”,角色定义的好坏直接影响智能体输出的风格和专业性。角色定义的重要性让智能体具备明确身份,例如“你是一位专业理财顾问”或“你是一个幽默的文案创作助手”。角色限定了模型知识输出的范围,使回答更专业、更贴合预期。实战示例模糊Prompt给我一些投资建议。你可以投资股票或者基金。优化Prompt你是一位具有10年经验的专业理财顾问,请给我针对30岁男性,年收入20万,风险偏中等的投资组合建议。

公众号:AI前沿侦探 1304

红黑树解析:map与set底层原理

本文解析了C++ STL中map和set容器的底层红黑树实现原理。红黑树是一种自平衡二叉搜索树,通过颜色调整和旋转操作保证O(log n)的时间复杂度。文章比较了不同数据结构的特性,说明STL选择红黑树的原因在于其平衡性、插入/删除代价和实现复杂度的最佳折中。详细介绍了红黑树的五大性质、节点结构、map与set的核心差异(KeyOfValue萃取方式),以及插入/删除的核心操作流程。最后对比了各容器的时间复杂度,并列举了面试常见问题。全文揭示了STL如何通过红黑树实现高效有序关联容器的关键技术。

likuolei的博客 423

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

从红黑树到STL map/set:C++有序关联容器实现原理与工程实践

在数据结构与算法领域,二叉搜索树是实现高效查找、插入和删除操作的基础数据结构。为了克服普通二叉搜索树在极端情况下退化为链表的性能问题,平衡二叉搜索树应运而生,它通过特定的平衡规则和旋转操作,确保树的高度维持在O(log n)级别,从而保证了操作的稳定效率。红黑树作为一种广泛应用的近似平衡二叉搜索树,通过红黑着色规则和旋转调整,在维护成本和操作效率之间取得了优异平衡,其对数级的时间复杂度使其成为工程实践中的关键技术。这一特性在需要有序数据存储和快速检索的应用场景中价值显著,例如数据库索引、内存缓存和C++标准

weixin_30740295的博客 455

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

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

C++ 红黑树实战:使用三层封装实现 STL 风格 map 与 set

主要内容是模仿STL的风格设计一个三层封装的红黑树以及说明了仿函数在关联式容器中的效用

2502_91499791的博客 397

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C++ STL map/set底层实现:红黑树封装与核心原理详解

在C++编程中,关联容器是解决高效查找与键值映射问题的核心数据结构。其底层通常基于平衡二叉搜索树(如红黑树)实现,通过维护元素的有序性,确保插入、删除和查找操作的时间复杂度稳定在O(log n)。这种设计不仅提供了稳定的性能保障,还支持高效的范围查询和有序遍历,在字典、缓存、去重等场景中具有重要技术价值。理解其封装原理,特别是迭代器设计、模板应用和内存管理,是深入掌握STL的关键。本文以红黑树为例,剖析map和set的底层实现,探讨自定义比较器、异常安全等工程实践问题,帮助开发者从API使用者转变为容器设计

weixin_34101229的博客 322

从零实现C++红黑树Map/Set:深入理解STL容器底层原理与设计

在C++标准模板库中,关联容器如map和set是组织有序数据的关键组件,其底层通常基于红黑树实现,以保障O(log n)的稳定操作性能。红黑树作为一种自平衡二叉搜索树,通过节点着色规则和旋转操作维护近似平衡,在查找效率与维护成本间取得了工程实践中的最优权衡。理解其插入、删除的平衡调整逻辑,不仅能深化对数据结构与算法的掌握,更是优化高性能专用容器、定制内存分配策略的基石。通过模拟实现红黑树及其迭代器体系,开发者可以透彻领悟STL的泛型设计哲学与模板编程技巧,例如通过KeyOfT仿函数实现同一棵树对Map和Se

weixin_33850015的博客 396

C++ STL红黑树实现与set/map容器详解

红黑树作为高效的自平衡二叉搜索树,是理解STL关联容器set和map实现原理的关键。其通过颜色标记和旋转操作维持O(log n)时间复杂度,在数据插入、删除时保持动态平衡。这种数据结构广泛应用于需要有序存储和快速查找的场景,如数据库索引、内存缓存等。STL中的set和map容器基于红黑树实现,其中set存储唯一键值,map存储键值对,两者都保持了元素的有序性。通过分析节点结构、旋转操作和插入平衡修复等核心机制,可以深入掌握STL容器的底层实现原理,为高性能C++开发奠定基础。

weixin_34087307的博客 370

C++红黑树实现STL set/map核心原理与优化

红黑树作为平衡二叉搜索树的经典实现,通过严格的颜色规则和旋转操作保证O(log n)时间复杂度,是C++ STL中set/map容器的底层数据结构。其核心设计哲学在于平衡插入/删除效率与有序性维护,相比哈希表更适合需要范围查询的场景。在工程实现中,节点结构设计、内存管理优化和迭代器兼容性是关键挑战。通过模拟实现红黑树,开发者不仅能深入理解STL容器工作原理,还能掌握数据结构设计中的异常安全、模板泛型和性能调优等高级技巧,这对构建高性能C++应用具有重要意义。

weixin_33827590的博客 785

set 和 map: set 和 map 的实现

关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的 键值对,在数据检索时比序列式容器效率更高。

2301_80468112的博客 959

红黑树模拟实现

红黑树是一种自平衡二叉查找树,通过颜色约束(红黑节点交替)确保近似平衡,保证操作时间复杂度为O(log n)。其性质包括:根节点为黑、无连续红节点、各路径黑节点数相同。插入操作分为三种情况处理:当父节点和叔节点为红时变色;当叔节点为黑时通过单旋或双旋调整。代码实现包括节点定义、旋转操作和插入时的颜色调整逻辑,通过向上回溯维护平衡特性。

2302_80061080的博客 1440

map根据key删除_map和set有什么区别,他们又是如何实现的?

1.AVLTree和RBTree的实现(map和set的底层实现)2.map和set都是C++的关联容器,其底层实现都是红黑树(RB-Tree)。由于 map 和set所开放的各种操作接口,RB-tree 也都提供了,所以几乎所有的 map 和set的操作行为,都只是转调 RB-tree 的操作行为。3.map和set的区别在于:map中的元素是key-value(键值对)对:关键字起到索引的作用...

weixin_39726267的博客 290

从红黑树原理到C++ Map/Set实现:平衡二叉搜索树的工程实践

平衡二叉搜索树是计算机科学中用于维护有序数据集合并支持高效查找、插入与删除操作的核心数据结构。其核心原理在于通过特定的平衡规则(如红黑树的颜色与路径约束)动态调整树形结构,确保树高保持对数级别,从而将操作时间复杂度稳定在O(log n)。这一特性在需要动态维护有序数据集且频繁进行增删查改的场景中具有极高的技术价值,例如数据库索引、内存键值存储、范围查询等。红黑树作为平衡二叉搜索树的一种经典实现,因其在插入与删除时所需的旋转操作相对较少,在工程实践中被广泛采用。C++标准库中的std::map和std::se

weixin_34337381的博客 483

map和set的模拟实现

map和set的底层是红黑树,现在我们就用红黑树来封装map和set,前提是我们用一个模板来封装map和set。

lihaolihao111111的博客 665

红黑树原理与STL map/set实现详解

红黑树是一种高效的自平衡二叉查找树,通过颜色约束和旋转操作维护近似平衡,确保查找、插入和删除操作的时间复杂度稳定在O(log n)。作为C++ STL中map和set容器的底层实现,红黑树相比AVL树在频繁修改场景下更具优势。其核心原理包括节点着色规则、旋转操作和平衡修复算法,广泛应用于需要快速查找和有序遍历的场景。本文深入解析红黑树的数据结构设计、平衡维护机制及其在STL容器中的具体实现,帮助开发者理解这一重要数据结构的工程实践价值。

weixin_34049948的博客 426
上一篇: 基于Vector实现的Map类 《C++程序设计语言》第13章
下一篇: C++ 黑白棋游戏的实现
laochen46
博客等级 码龄18年 13粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值