【STL源码剖析】第五章 关联式容器 之 树的导览

2024-08-22 13:08

本文主要是介绍【STL源码剖析】第五章 关联式容器 之 树的导览,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第五章 关联式容器

标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多建集合)和multimap(多键映射表)。这些容器的底层实现极值均以RB-tree(红黑树)完成。RB-tree也是一个独立容器,但并不开放给外界使用。

此外,SGI STL还提供了一个不在标准规格之列的关联式容器:hash table(散列表),以及以此hash table为底层实现机制而完成的hash_set(散列集合)、hash_map(散列映射表)、hash_multiset(散列多键集合)、hash_multimap(散列多键映射表)。

关联式容器(associative containers)

所谓关联式容器,观念上类似关联式数据库(实际上则简单许多):每笔数据(每个元素)都有一个键值(key)和一个实值(value)。当元素被插入关联式容器中时,容器内部结构(可能是RB-tree,也可能是hash-table)便依照其键值大小,以某种特定规则将这个元素置于适当位置。关联式容器没有所谓的头尾(只有最大元素和最小元素),所以不会有所谓的push_back()、push_front()、pop_back()、pop_front()、begin()、end()这样的操作行为。

树的导览

树由节点(nodes)和边(edges)构成。整棵树有一个最上端节点,称为根节点(root)。每个节点可以拥有具有方向性的边(directed edges),用来和其他节点相连。相连节点之中,在上者称为父节点(parent),在下者称为子节点(child)。无子节点者称为叶节点(leaf)。子节点可以存在多个,如果最多只允许两个子节点,即所谓二叉树(binary tree)。不同的节点如果拥有相同的父节点,则彼此互为兄弟节点(siblings)。根节点至任何节点直接有唯一路径(path),路径所经过的边数,称为路径长度(length)。根节点至任一节点的路径长度,即所谓该节点的深度(depth)。根节点的深度永远是0。某节点至其最深子节点(叶节点)的路径长度,称为该节点的高度(height)。整棵树的高度,便以根节点的高度来代表。任何节点的大小(size)是指其所有子代(包括自己)的节点总数。

二叉搜索树

所谓二叉树,其意义是:"任何节点最多只允许两个子节点",即左右子节点。递归方式定义:”一个二叉树如果不为空,便是一个根节点和左右两子树构成;左右子树都可能为空“。二叉树应用广泛,例子:编译器表达式树、哈夫曼编码树。

所谓二叉搜索树,可提供对数实际的元素插入和访问 。二叉搜索树的节点放置规则是:任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。因此,从根节点一直往左走,直至无路可走,即得最小元素;从根节点一直往右走,直至无右路可走,即得最大元素。

二叉搜索树插入新元素时,可以从根节点开始,遇键值较大者就向左,遇键值较小者就向右,一直到尾端,即为插入点。

二叉搜索树移除操作。欲删除就节点A,情况可分两种。如果A只有一个子节点,我们就直接将A的子节点连至A的父节点,并将A删除。如果A有两个子节点,我们就以右子树内的最小节点取代A。注意,右子书的最小节点极易获得。

平衡二叉搜索树

所谓树形平衡与否,并没有一个绝对的测量标准。“平衡”的大致意义是:没有任何一个节点过深。不同的平衡条件,造就不同的效率表现,以及不同的实现复杂度。有数种特殊结构如AVL-tree、RB-tree、AA-tree,均可实现平衡二叉搜索树,它们比一般二叉搜索树复杂,因此,插入节点和删除节点的平均时间也比较长,但是它们可以避免极难应付的最坏情况,况且由于它们总数保持某种程度的平衡,所以元素的访问时间平均而言也就比较少,一般而言其搜素时间可节省25%左右。

AVL tree

AVL tree是一个“加上了额外平衡条件”的二叉搜索树。其平衡条件的建立是为了确保整棵树的深度为O(logN)。AVL tree要求任何节点的左右子树高度相差最多为1。

如图AVL tree,插入了节点11之后,灰色节点违反了AVL tree的平衡条件。由于只有“插入点至根节点”路径上的各节点可能改变平衡状态,因此,只要调整其中最深的那个节点,便可使整棵树重新获得平衡。

前面说过,只要调整“插入节点至根节点”路径上,平衡状态被破坏之各节点种最深的那一个,便可使得整棵树重新获得平衡。假设该最深节点X,由于节点最多拥有两个子节点,二所谓“平衡被破坏”意味着X的左右两棵子树的高度相差2,因此可以分为一些四种情况:

  1. 插入点位于X的左子节点的左子树——左左。

  2. 插入点位于X的左子节点的右子树——左右。

  3. 插入点位于X的右子节点的左子树——右左。

  4. 插入点位于X的右子节点的右子树——右右。

情况1,4彼此对称,称为外侧插入,可以采用单选转操作调整解决。情况2,3彼此对此对此,称为内存插入,可采用双旋转调整解决。

单旋转

双旋转

这篇关于【STL源码剖析】第五章 关联式容器 之 树的导览的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1096359

相关文章

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

如何将Tomcat容器替换为Jetty容器

《如何将Tomcat容器替换为Jetty容器》:本文主要介绍如何将Tomcat容器替换为Jetty容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat容器替换为Jetty容器修改Maven依赖配置文件调整(可选)重新构建和运行总结Tomcat容器替

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

mysql关联查询速度慢的问题及解决

《mysql关联查询速度慢的问题及解决》:本文主要介绍mysql关联查询速度慢的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql关联查询速度慢1. 记录原因1.1 在一次线上的服务中1.2 最终发现2. 解决方案3. 具体操作总结mysql

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

MYSQL关联关系查询方式

《MYSQL关联关系查询方式》文章详细介绍了MySQL中如何使用内连接和左外连接进行表的关联查询,并展示了如何选择列和使用别名,文章还提供了一些关于查询优化的建议,并鼓励读者参考和支持脚本之家... 目录mysql关联关系查询关联关系查询这个查询做了以下几件事MySQL自关联查询总结MYSQL关联关系查询

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操