平衡树之RB-tree

  1 #include <memory>
  2
  3 template<class T>
  4 struct rb_node
  5 {
  6     T key;
  7     bool color;//true red | false black
  8     std::shared_ptr<rb_node> lchild, rchild, parent;
  9
 10     rb_node(T key, bool color = true, std::shared_ptr<rb_node> lchild = nullptr,
 11         std::shared_ptr<rb_node> rchild = nullptr, std::shared_ptr<rb_node> parent = nullptr)
 12         :key(key)//此处不能使用this:现在对象还没被构建起来
 13     {
 14         //赋值,初始化在初始化列表中执行
 15         this->color = color;
 16         this->lchild = lchild;
 17         this->rchild = rchild;
 18         this->parent = parent;
 19     }
 20 };
 21
 22 template<class T>
 23 class rb_tree
 24 {
 25 private:
 26     std::shared_ptr<rb_node<T>> root;
 27     std::shared_ptr<rb_node<T>> nil;//叶节点
 28     void left_rotation(std::shared_ptr<rb_node<T>> a)
 29     {
 30         if (a == nullptr) return;
 31         std::shared_ptr<rb_node<T>> b = a->rchild;
 32         if (b == nullptr) return;
 33         if (b->lchild != nullptr)
 34             b->lchild->parent = a;
 35         a->rchild = b->lchild;
 36
 37         if (a->parent == nil)
 38             root = b;//rbtree的root以nil为父节点
 39         else
 40         {
 41             if (a->parent->lchild == a)
 42                 a->parent->lchild = b;
 43             else
 44                 a->parent->rchild = b;
 45         }
 46         b->parent = a->parent;
 47
 48         b->lchild = a;
 49         a->parent = b;
 50     }
 51     void right_rotation(std::shared_ptr<rb_node<T>> a)
 52     {
 53         if (a == nullptr) return;
 54         std::shared_ptr<rb_node<T>> b = a->lchild;
 55         if (b == nullptr) return;
 56         if (b->rchild != nullptr)
 57             b->rchild->parent = a;
 58         a->lchild = b->rchild;
 59
 60         if (a->parent == nil)
 61             root = b;
 62         else
 63         {
 64             if (a->parent->lchild == a)
 65                 a->parent->lchild = b;
 66             else
 67                 a->parent->rchild = b;
 68         }
 69         b->parent = a->parent;
 70
 71         b->rchild = a;
 72         a->parent = b;
 73     }
 74
 75 public:
 76     rb_tree()
 77     {
 78         root = nullptr;
 79         T key;
 80         nil = std::make_shared<rb_node<T>>(key, false);
 81     }
 82     void insert(T key)
 83     {
 84         std::shared_ptr<rb_node<T>> tmp = std::make_shared<rb_node<T>>(key, true, nil, nil, nil);
 85         std::shared_ptr<rb_node<T>> ptr = root;
 86
 87         //情况1:树为空
 88         if (ptr == nullptr)
 89         {
 90             tmp->color = false;
 91             root = tmp;
 92             return;
 93         }
 94         while (true)
 95         {
 96             if (key <= ptr->key)
 97             {
 98                 if (ptr->lchild == nil) break;
 99                 ptr = ptr->lchild;
100             }
101             else
102             {
103                 if (ptr->rchild == nil) break;
104                 ptr = ptr->rchild;
105             }
106         }
107
108         if (key <= ptr->key)
109             ptr->lchild = tmp;
110         else
111             ptr->rchild = tmp;
112         tmp->parent = ptr;
113
114         while(true)
115         {
116             if (ptr == nil)//注意root可能被情况三修改为red,记得加特判
117             {
118                 tmp->color = false;
119                 root = tmp;
120                 return;
121             }
122
123             //情况2:插入节点的父节点为黑色
124             if (!ptr->color) return;
125
126             /*情况3:插入节点的父节点和叔节点都存在且都为红色*/
127             if (ptr->parent->lchild->color && ptr->parent->rchild->color)
128             {
129                 ptr->parent->color = true;
130                 ptr->parent->lchild->color = false;
131                 ptr->parent->rchild->color = false;
132
133                 tmp = ptr->parent;
134                 ptr = tmp->parent;
135                 continue;
136             }
137             if (ptr->parent->lchild == ptr)
138             {
139                 //情况4:右旋
140                 if (tmp == ptr->lchild)
141                 {
142                     ptr->parent->color = true;
143                     ptr->color = false;
144                     right_rotation(ptr->parent);
145                     return;
146                 }
147                 else
148                 {
149                     //情况5:左旋 + 右旋
150                     left_rotation(ptr);
151                     tmp = ptr;
152                     ptr = tmp->parent;
153                     continue;
154                 }
155             }
156             else
157             {
158                 //情况4:左旋
159                 if (tmp == ptr->rchild)
160                 {
161                     ptr->parent->color = true;
162                     ptr->color = false;
163                     left_rotation(ptr->parent);
164                     return;
165                 }
166                 else
167                 {
168                     //情况5:右旋+左旋
169                     right_rotation(ptr);
170                     tmp = ptr;
171                     ptr = tmp->parent;
172                     continue;
173                 }
174             }
175         }
176     }
177     void earse(T key)
178     {
179         //待续
180     }
181 };
时间: 2025-01-07 16:08:49

平衡树之RB-tree的相关文章

STL RB Tree(红黑树)分析

当我2014年上半年看内核代码的时候,进程调度用的就是RB  Tree,而现在分析STL源码的时候发现Set和Map也使用了这个数据结构,说明了RBTree的使用时如此的广泛,所以我花了两天时间看了这,分三部分来说明,首先我要说明下红黑树的基本概念,然后说明下STL中的RB Tree的迭代器,最后说下STL中RB Tree容器的实现. 一.红黑树的基本概念 红黑树是平衡二叉搜索树的一种(平衡二叉搜索树中又有AVL Tree),满足二叉搜索树的条件外,还应买足下面的4个条件 1) 每个节点不是红色

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

stl_tree.h 这是整个STL中最复杂的数据结构,也是我接触到的最复杂的数据结构之一 /** Red-black tree class, designed for use in implementing STL associative containers (set, multiset, map, and multimap). The insertion and deletion algorithms are based on those in Cormen, Leiserson, and

重学数据结构系列之——平衡树之SB Tree(Size Blanced Tree)

平衡树 1.定义 对于每个结点,左右两个子树的高度差的绝对值不超过1,或者叫深度差不超过1 为什么会出现这样一种树呢? 假如我们按照1-n的顺序插入到二叉排序树中,那么二叉排序树就退化成了一个有序链表,效率大大降低. 2.有关概念 所有平衡树基本由以下三个特征组成: 1.自平衡条件 2.旋转操作 3.旋转的触发 平衡树通过设置合理的自平衡条件,使得二叉排序树的查找.插入等操作的性能不至于退化到 O(n)O(n),并且在进行二叉排序树的查找.插入等操作时进行判断,如果满足其中某个旋转的触发条件,则

java数据结构——红黑树(R-B Tree)

红黑树相比平衡二叉树(AVL)是一种弱平衡树,且具有以下特性: 1.每个节点非红即黑; 2.根节点是黑的; 3.每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的; 4.如图所示,如果一个节点是红的,那么它的两儿子都是黑的; 5.对于任意节点而言,其到叶子点树NULL指针的每条路径都包含相同数目的黑节点; 6.每条路径都包含相同的黑节点 原文地址:https://www.cnblogs.com/hardhp74520/p/11317028.html

树-红黑树(R-B Tree)

红黑树概念 特殊的二叉查找树,每个节点上都有存储位表示节点的颜色是红(Red)或黑(Black).时间复杂度是O(lgn),效率高. 特性: (1)每个节点或者是黑色,或者是红色. (2)根节点是黑色. (3)每个叶子节点(NIL)是黑色.(只为空(NIL或null)的节点) (4)如果一个节点是红色的,则它的子节点必须是黑色的.(黑结点可连续,红结点不能连续) (5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点. 定理:一棵含有n个节点的红黑树的高度至多为2log(n+1).

Java集合源码分析之基础(六):红黑树(RB Tree)

当插入元素9时,这时是需要调整的第一种情况,结果 如下: 插入9 红黑树规则4中强调不能有两个相邻的红色结点,所以此时我们需要对其进行调整.调整的原则有多个相关因素,这里的情况是,父结点10是其祖父结点1(父结点的父结点)的右孩子,当前结点9是其父结点10的左孩子,且没有叔叔结点(父结点的兄弟结点),此时需要进行两次旋转,第一次,以父结点10右旋: 作者:大大纸飞机链接:https://www.jianshu.com/p/3958a1a11cb0来源:简书简书著作权归作者所有,任何形式的转载都请

[转]SGI STL 红黑树(Red-Black Tree)源代码分析

STL提供了许多好用的数据结构与算法,使我们不必为做许许多多的重复劳动.STL里实现了一个树结构-Red-Black Tree,它也是STL里唯一实现的一个树状数据结构,并且它是map, multimap,set,multiset的底层实现,如果学会了Red-Black Tree,那么对我们高效的运用STL是很有帮助的. 1. 什么是红黑树 红黑树是二叉查找树的一种,由于它能够保证树的高度比较底,所以是一种性能较好的查找树.它需要满足以下几条性质: 1.每个结点或是红的,或是黑的 2.根结点是黑

数据结构 - 红黑树(Red Black Tree)插入详解与实现(Java)

最终还是决定把红黑树的篇章一分为二,插入操作一篇,删除操作一篇,因为合在一起写篇幅实在太长了,写起来都觉得累,何况是阅读并理解的读者. 红黑树删除操作请参考 数据结构 - 红黑树(Red Black Tree)删除详解与实现(Java) 现在网络上最不缺的就是对某个知识点的讲解博文,各种花样标题百出,更有类似"一文讲懂xxx","史上最简单的xxx讲解","xxx看了还不懂你打我"之类云云.其中也不乏有些理论甚至是举例都雷同的两篇不同文章,至于作

AVL 平衡树

AVL是一种平衡二叉树,它通过对二叉搜索树中的节点进行旋转使得二叉搜索树达到平衡.AVL在所有的平衡二叉搜索树中具有最高的平衡性. 定义 平衡二叉树或者为空树或者为满足如下性质的二叉搜索树: 左右子树的高度之差绝对值不超过1 左右子树仍然为平衡二叉树 定义平衡因子 BF(x) = x的左子树高度 - x的右子树的高度.平衡二叉树的每个节点的平衡因子只能为-1, 0, 1. 维持平衡思想 若二叉树当前为平衡状态,此时插入/删除一个新的节点,此时有可能造成二叉树不满足平衡条件,此时需要通过对节点进行

[SinGuLaRiTy] 平衡树

[SinGuLaRiTy-1009] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 二叉查找树 二叉查找树是指具有下列性质的非空二叉树: ⑴若根结点的左子树不空,则左子树的所有结点值均小于根结点值: ⑵若根结点的右子树不空,则右子树的所有结点值均不小于根结点值: ⑶根结的左右树也分别为二叉排序树: 显然,对二叉排序树进行中序遍历,可得出结点值递增的排序序列. eg. 下图即是一棵二叉查找树: 其中序遍历为8,11,23,39,46,68