返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ STL容器中红黑树部分模拟实现的示例分析
  • 357
分享到

C++ STL容器中红黑树部分模拟实现的示例分析

2023-06-21 23:06:56 357人浏览 泡泡鱼
摘要

这篇文章主要介绍了c++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、红黑树的概念红黑树(Red Black Tree

这篇文章主要介绍了c++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

一、红黑树的概念

红黑树(Red Black Tree),是在计算机科学中用到的一种数据结构,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。

C++ STL容器中红黑树部分模拟实现的示例分析

二、红黑树的性质

每个结点不是红色就是黑色;

根节点是黑色的;

如果一个节点是红色的,则它的两个孩子结点是黑色的;

对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点;

每个叶子结点都是黑色的(此处的叶子结点指的是空结点);

满足上面的性质,红黑树就能保证其最长路径中节点个数不会超过最短路径节点个数的两倍。

三、红黑树节点的定义

enum Colour//红黑树颜色枚举{RED,BLACK,}; template<class K, class V>struct RBTreenode//节点结构体{RBTreeNode<K, V>* _left;//左子树RBTreeNode<K, V>* _right;//右子树RBTreeNode<K, V>* _parent;//父节点 pair<K, V> _kv; Colour _col; RBTreeNode(const pair<K, V>& kv)//构造函数: _left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv), _col(RED){}};

插入时默认为红色节点,因为红色可能会破坏规则3,黑色一定会破坏规则4,所以默认红色。

四、红黑树结构 

为了后续实现关联式容器简单,红黑树的实现中增加一个头结点,因为跟节点必须为黑色,为了与根节点进行区分,将头结点给成黑色,并且让头结点的 parent 域指向红黑树的根节点,left域指向红黑树中最小的节点,right域指向红黑树中最大的节点,如下:

C++ STL容器中红黑树部分模拟实现的示例分析

五、 红黑树的插入操作

红黑树是在二叉搜索树的基础上加上其平衡限制条件,因此红黑树的插入可分为两步:

按照二叉搜索的树规则插入新节点:

pair<Node*, bool> Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return make_pair(_root, true);} Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else{return make_pair(cur, false);}} Node* newNode = new Node(kv);newNode->_col = RED;if (parent->_kv.first > kv.first){parent->_left = newNode;newNode->_parent = parent;}else{parent->_right = newNode;newNode->_parent = parent;}cur = newNode; while (parent && parent->_col == RED)//违反规则三{ } _root->_col = BLACK;//插入结束再次将根变为黑 return make_pair(cur, true);}

检测新节点插入后,红黑树的性质是否造到破坏

因为新节点的默认颜色是红色,因此:如果其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整;但当新插入节点的双亲节点颜色为红色时,就违反了性质三不能有连在一起的红色节点,此时需要对红黑树分情况来讨论:

cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点

情况一:cur为红,p为红,g为黑,u存在且为红

C++ STL容器中红黑树部分模拟实现的示例分析

如果g是根节点,调整完成后,需要将g改为黑色,如果g是子树,g一定有父节点,且如果为红色呃,继续向上调整。

C++ STL容器中红黑树部分模拟实现的示例分析

将p,u改为黑,g改为红,然后把g当成cur,继续向上调整 。

情况二: cur为红,p为红,g为黑,u不存在/u为黑

C++ STL容器中红黑树部分模拟实现的示例分析

u的情况有两种:

如果u节点不存在,则cur一定是新插入节点,因为如果cur不是新插入节点,则cur和p一定有一个节点的颜色是黑色,就不满足性质4:每条路径黑色节点个数相同。

如果u节点存在,则其一定是黑色的,那么cur节点原来的颜色一定是黑色的,现在看到其是红色的原因是因为cur的子树在调整的过程中将cur节点的颜色由黑色改成红色。

p为g的左孩子,cur为p的左孩子,则进行右单旋转;

p为g的右孩子,cur为p的右孩子,则进行左单旋转。

p变黑,g变红。

情况三: cur为红,p为红,g为黑,u不存在/u为黑

C++ STL容器中红黑树部分模拟实现的示例分析

C++ STL容器中红黑树部分模拟实现的示例分析

需要进行双旋。

代码实现:

while (parent && parent->_col == RED)//违反规则三{Node* grandfather = parent->_parent; if (parent == grandfather->_left)//左半边{Node* uncle = parent->_right; if (uncle && uncle->_col == red)//情况一{uncle->_col = BLACK;grandfather->_col = RED;parent->_col = BLACK; cur = grandfather;//迭代parent = cur->_parent;}else//情况2.3{if (cur == parent->_left)//单侧{RotateR(grandfather); grandfather->_col = RED;parent->_col = BLACK;}else//折{RotateL(parent);RotateR(grandfather); cur->_col = BLACK;grandfather->_col = RED;} break;//黑色数量无变化,不需要向上}}else         // parent == grandfather->_right{Node* uncle = parent->_left;if (uncle && uncle->_col == red)//情况一{uncle->_col = BLACK;grandfather->_col = RED;parent->_col = BLACK; cur = grandfather;//迭代parent = cur->_parent;}else//情况2.3{if (cur == parent->_right)//单侧{RotateL(grandfather); grandfather->_col = RED;parent->_col = BLACK;}else//折{RotateR(parent);RotateL(grandfather); cur->_col = BLACK;grandfather->_col = RED;} break;}}}

六、代码

#pragma once#include<iOStream>#include<assert.h> using namespace std; enum Colour//红黑树颜色枚举{RED,BLACK,}; template<class K, class V>struct RBTreeNode//节点结构体{RBTreeNode<K, V>* _left;//左子树RBTreeNode<K, V>* _right;//右子树RBTreeNode<K, V>* _parent;//父节点 pair<K, V> _kv; Colour _col; RBTreeNode(const pair<K, V>& kv)//构造函数: _left(nullptr), _right(nullptr), _parent(nullptr), _kv(kv), _col(RED){}}; template<class K, class V>class RBTree{typedef RBTreeNode<K, V> Node;private:Node* _root; void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;Node* parentP = parent->_parent; if (subLR)//左子树的右子树连接到父的右subLR->_parent = parent; parent->_left = subLR;subL->_right = parent;parent->_parent = subL; // 如果parent是根节点,根新指向根节点的指针if (parent == _root){_root = subL;subL->_parent = nullptr;}else{// 如果parent是子树,可能是其双亲的左子树,也可能是右子树if (parentP->_left == parent)parentP->_left = subL;elseparentP->_right = subL; subL->_parent = parentP;}} void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;Node* parentP = parent->_parent; if (subRL)subRL->_parent = parent; parent->_right = subRL;subR->_left = parent;parent->_parent = subR; // 如果parent是根节点,根新指向根节点的指针if (parent == _root){_root = subR;subR->_parent = nullptr;}else{// 如果parent是子树,可能是其双亲的左子树,也可能是右子树if (parentP->_left == parent)parentP->_left = subR;elseparentP->_right = subR; subR->_parent = parentP;}} void _Destory(Node* root){if (root == nullptr){return;} _Destory(root->_left);_Destory(root->_right); delete root;} public:RBTree():_root(nullptr){} ~RBTree(){_Destory(_root);_root = nullptr;} Node* Find(const K& key){Node* cur = _root;while (cur){if (cur->_kv.first > key){cur = cur->_left;}else if (cur->_kv < key){cur = cur->_right;}else{return cur;}} return nullptr;} pair<Node*, bool> Insert(const pair<K, V>& kv){if (_root == nullptr){_root = new Node(kv);_root->_col = BLACK;return make_pair(_root, true);} Node* parent = nullptr;Node* cur = _root;while (cur){if (cur->_kv.first > kv.first){parent = cur;cur = cur->_left;}else if (cur->_kv.first < kv.first){parent = cur;cur = cur->_right;}else{return make_pair(cur, false);}} Node* newNode = new Node(kv);newNode->_col = RED;if (parent->_kv.first > kv.first){parent->_left = newNode;newNode->_parent = parent;}else{parent->_right = newNode;newNode->_parent = parent;}cur = newNode; while (parent && parent->_col == RED)//违反规则三{Node* grandfather = parent->_parent; if (parent == grandfather->_left)//左半边{Node* uncle = parent->_right; if (uncle && uncle->_col == red)//情况一{uncle->_col = BLACK;grandfather->_col = RED;parent->_col = BLACK; cur = grandfather;//迭代parent = cur->_parent;}else//情况2.3{if (cur == parent->_left)//单侧{RotateR(grandfather); grandfather->_col = RED;parent->_col = BLACK;}else//折{RotateL(parent);RotateR(grandfather); cur->_col = BLACK;grandfather->_col = RED;} break;//黑色数量无变化,不需要向上}}else         // parent == grandfather->_right{Node* uncle = parent->_left;if (uncle && uncle->_col == red)//情况一{uncle->_col = BLACK;grandfather->_col = RED;parent->_col = BLACK; cur = grandfather;//迭代parent = cur->_parent;}else//情况2.3{if (cur == parent->_right)//单侧{RotateL(grandfather); grandfather->_col = RED;parent->_col = BLACK;}else//折{RotateR(parent);RotateL(grandfather); cur->_col = BLACK;grandfather->_col = RED;} break;}}} _root->_col = BLACK;//插入结束再次将根变为黑 return make_pair(newNode, true);}};

感谢你能够认真阅读完这篇文章,希望小编分享的“C++ STL容器中红黑树部分模拟实现的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网其他教程频道,更多相关知识等着你来学习!

--结束END--

本文标题: C++ STL容器中红黑树部分模拟实现的示例分析

本文链接: https://lsjlt.com/news/301469.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++ STL容器中红黑树部分模拟实现的示例分析
    这篇文章主要介绍了C++ STL容器中红黑树部分模拟实现的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、红黑树的概念红黑树(Red Black Tree...
    99+
    2023-06-21
  • C++ STL容器详解之红黑树部分模拟实现
    目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树结构 五、 红黑树的插入操作六、代码总结一、红黑树的概念 红黑树(Red Black Tree),是在计算机科学中用...
    99+
    2024-04-02
  • C++中红黑树的示例分析
    这篇文章将为大家详细讲解有关C++中红黑树的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。红黑树红黑树的概念红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以...
    99+
    2023-06-29
  • C++数据结构红黑树的示例分析
    这篇文章给大家分享的是有关C++数据结构红黑树的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概念和性质红黑树的概念: 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或...
    99+
    2023-06-29
  • ConcurrentHashMap: 红黑树代理类的示例分析
    小编给大家分享一下ConcurrentHashMap: 红黑树代理类的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、TreeBin内部类分析TreeB...
    99+
    2023-06-15
  • C++中STL vector的模拟实现示例
    这篇文章主要介绍C++中STL vector的模拟实现示例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. vector的介绍和使用vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存...
    99+
    2023-06-14
  • c++中vector模拟实现的示例分析
    这篇文章将为大家详细讲解有关c++中vector模拟实现的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、vector是什么?vector是表示可变大小数组的序列容器,它也采用连续存储空间来存储...
    99+
    2023-06-14
  • Java数据结构之红黑树的示例分析
    小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、红黑树所处数据结构的位置:在JDK源码中, 有treeMap...
    99+
    2023-05-30
    java
  • C++实现STL容器的示例
    各大容器的特点: 1.可以用下标访问的容器有(既可以插入也可以赋值):vector、deque、map; 特别要注意一下,vector和deque如果没有预先指定大小,是不能用下标法...
    99+
    2024-04-02
  • 分析红黑树在C++云计算服务中的应用模式
    红黑树是一种自平衡二叉查找树,它在C++云计算服务中有着广泛的应用模式。在云计算服务中,红黑树通常被用作数据结构的基础,用于实现高效...
    99+
    2024-04-26
    C++
  • 基于红黑树插入操作原理及java实现的示例分析
    这篇文章主要介绍基于红黑树插入操作原理及java实现的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK。红黑树具有以下...
    99+
    2023-05-30
    java
  • C语言实现手写红黑树的示例代码
    目录前沿红黑树代码测试前沿 写C的红黑树前建议先看我博客这篇文章Java-红黑树 主要看原理 红黑树代码 #ifndef STUDY_RBTREE_H #define ...
    99+
    2024-04-02
  • C++中指针,引用和STL的示例分析
    这篇文章主要介绍C++中指针,引用和STL的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!对象的定义:对象是指一块能存储数据并具有某种类型的内存空间一个对象a,它有值和地址;运行程序时,计算机会为该对象分配存...
    99+
    2023-06-29
  • 实现Bean容器的示例分析
    实现Bean容器的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、Spring Bean 容器是什么Spring 包含并管理应用对象的配置和生命周期,...
    99+
    2023-06-15
  • C++深入分析STL中map容器的使用
    目录1、map容器2、map容器原理3、map容器函数接口4、使用示例1、map容器 map是C++ STL的一个关联容器,它提供一对一的数据处理能力。其中,各个键值对的键和值可以是...
    99+
    2024-04-02
  • 分析C++中红黑树的时间复杂度和空间复杂度
    红黑树是一种自平衡的二叉搜索树,它具有以下特点: 每个节点要么是红色,要么是黑色。 根节点是黑色。 每个叶子节点(NIL节点)是黑...
    99+
    2024-04-26
    C++
  • C语言中二叉树的示例分析
    这篇文章主要为大家展示了“C语言中二叉树的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中二叉树的示例分析”这篇文章吧。树概念及结构树是一种 非线性 的数据结构,它是由 n ( n...
    99+
    2023-06-29
  • C语言实现手写Map(数组+链表+红黑树)的示例代码
    目录要求结构红黑树和链表转换策略hash使用要求 需要准备数组集合(List) 数据结构 需要准备单向链表(Linked) 数据结构 需要准备红黑树(Rbtree)数据结构 需要准备...
    99+
    2024-04-02
  • Vue模拟实现数据驱动的示例分析
    这篇文章主要为大家展示了“Vue模拟实现数据驱动的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vue模拟实现数据驱动的示例分析”这篇文章吧。一、前言之...
    99+
    2024-04-02
  • Linux下模拟实现进度条的示例分析
    这篇文章将为大家详细讲解有关Linux下模拟实现进度条的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Linux下模拟实现进度条 在Linux系统下模拟进度条,首先需要了解一些简单基础知...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作