【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

相关文章

Spring核心思想之浅谈IoC容器与依赖倒置(DI)

《Spring核心思想之浅谈IoC容器与依赖倒置(DI)》文章介绍了Spring的IoC和DI机制,以及MyBatis的动态代理,通过注解和反射,Spring能够自动管理对象的创建和依赖注入,而MyB... 目录一、控制反转 IoC二、依赖倒置 DI1. 详细概念2. Spring 中 DI 的实现原理三、

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。