当前位置:   article > 正文

【C++】红黑树(Red Black Tree)_红黑树c++

红黑树c++

 什么是红黑树

从概念上来讲,它是一种二叉搜索树,但每一个节点不是红色就是黑色,它保证最长路径不会比其他路径长出两倍

为什么能保证,就要看下面几条性质:

1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)

 

为什么满足了上面的性质就可以保证最长的不超过最短的两倍?

因为最短路径肯定是全黑,但是最长路径是黑红黑红,因为其保证了每条路径黑色节点数量要一致,所以最长的黑红最多也就等于两倍的黑

二叉树节点的定义

这里会跟AVL树有所不同,因为这里之后要复用到map,所以会稍作修改

首先为了区分颜色,我们就可以用到枚举:

  1. enum Color
  2. {
  3. Red,
  4. Black
  5. };

然后创建节点的结构体,这里跟AVLTree差不多

  1. template<class K,class V>
  2. struct RBTreeNode
  3. {
  4. pair<K, V> _kv;
  5. RBTreeNode<K, V>* _parent;
  6. RBTreeNode<K, V>* _left;
  7. RBTreeNode<K, V>* _right;
  8. Color _color;
  9. RBTreeNode(const pair<K,V>& kv)
  10. :_kv(kv)
  11. , _parent(nullptr)
  12. , _left(nullptr)
  13. , _right(nullptr)
  14. , _color(Red)
  15. {}
  16. };

顺便写一个构造函数,也很简单,把指针置为空,将里面的值用外面的拷贝一份,这里要注意的是,为什么插入节点的颜色要是红色。

这里我们插入节点是一定要给颜色的,给颜色就会出现两种情况:

3. 如果一个节点是红色的,则它的两个孩子结点是黑色的
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数目的黑色结点

如果我们插入红色,有可能会违反3,因为它的父亲节点可能是红色的,但如果我们插入黑色节点,那就一定会违反4,因为你在一条支路里面插入黑色节点,如何确保其他路上的黑色节点数量一样就是个问题 

红黑树的插入

先简单写一个红黑树的大框架出来

  1. template<class K, class V>
  2. class RBTree
  3. {
  4. typedef RBTreeNode<K, V> Node;
  5. private:
  6. Node* _root = nullptr;
  7. };

然后就可以考虑写插入了,这里需要提醒一下,是否还记得AVL树的旋转,这里红黑树也需要用到,如果不记得,这里放上另一篇博客的链接可供参考:

【C++】AVL_Knous的博客-CSDN博客

ok,最基本的先写上,如果这是一个空树,那最开始插入的就是根节点:

  1. //判断这是否为空树,是就直接插入
  2. if (_root == nullptr)
  3. {
  4. _root = new Node(kv);
  5. //根节点一定要是黑色
  6. _root->_color = Black;
  7. return true;
  8. }

然后,就可以开始插入了,插入部分根AVL基本一致

  1. Node* cur = _root;
  2. Node* parent = cur->_parent;
  3. while (cur)
  4. {
  5. if (cur->_kv.first > kv.first)
  6. {
  7. parent = cur;
  8. cur = cur->_left;
  9. }
  10. else if (cur->_kv.first < kv.first)
  11. {
  12. parent = cur;
  13. cur = cur->_right;
  14. }
  15. else
  16. return false;
  17. cur = new Node(kv);
  18. cur->_color = Red;
  19. if (cur = parent->_left)
  20. parent->_left = cur;
  21. else
  22. parent->_right = cur;

然后就是我们需要处理的地方,我们就开始判断:

假设,我们在这个位置插入,肯定是没问题的࿰

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/246214?site
推荐阅读