[TOC] # 概念 - 节点是红色或黑色。 - 根节点是黑色。 - 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点) - 每个Nil节点都是黑色 - 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 # 左旋转 左旋转过程: node x / \ 左旋转 / \ T1 x ---------> node T3 / \ / \ T2 T3 T1 T2 ``` /** Node<Key, Value>* leftRotate(Node<Key, Value> *node) { Node<Key, Value>* x = node->right; node->right = x->left; x->left = node; x->color = node->color; node->color = Node::RED; return x; } ``` # 右旋转 右旋转过程: ``` node x / \ 右旋转 / \ x T2 -------> y node / \ / \ y T1 T1 T2 ``` ``` Node<Key, value>* rightRotate(Node<Key, Value>* node) { Node<key, Value> *x = node->left; node->left = x->right; x->right = node; x->color = node->color; node->color = Node::RED; retu ``` # 颜色反转 ``` /* *颜色反转 * */ void flipColors(Node<Key, Value>* node) { node->color = Node::RED; node->left->color = Node::BLACK; node->right->color = Node::BLACK; } ``` # 插入节点过程 每次插入,跟二叉搜索树一样的递归过程,唯一多的功能是判断是否需要进行左旋转,右旋转或者颜色反转,最后需要一直保持根节点为黑色节点,过程如下图所示: ![](https://leanote.com/api/file/getImage?fileId=5d2d8f95ab64416644006dc6) ``` public: void add(const Key &k, const Value &v) { _root = add(_root, k, v); //最终根节点为黑色 _root->color = Node::BLACK; } private: /** * 返回插入元素后红黑树的根 */ Node<Key, Value>* add(Node<Key, Value>* root, const Key &k, const Value &v) { if (root == nullptr) { _size++; return new Node(k, v); } if (k < root->key) { root->left = add(root->left, k, v); } else if(k > root->key) { root->right = add(root->right, k, v); } else { root->value = v; } // 左节点黑色,右节点红色 if (isRed(root->right) && !isRed(root->left)) root = rightRotate(root); // 连续两个左子节点都是红色的,需要右旋转 if (isRed(root->left) && isRed(root->left->left)) root = rightRotate(root); // 左右子树都是红节点,直接翻转颜色即可 if (isRed(root->left) && isRed(root->right)) flipColors(root); return root; } ``` # 设计架构 ``` #ifndef __RBTREE_HPP #define __RBTREE_HPP //Author:Simon //Email:476941913@qq.com template<typename Key, typename Value> struct Node { enum color { RED, BLACK }; Key key; Value value; int color; Node *left; Node *right; Node(const Key &k,const Value &v):key(k),value(v),left(nullptr),right(nullptr),color(RED){} }; template<typename Key,typename Value> class RBTree { public: RBTree():_size(0),_root(nullptr); ~RBTree(); public: void add(const Key &k, const Value &v); private: Node<Key, Value>* leftRotate(Node<Key, Value> *node); Node<Key, value>* rightRotate(Node<Key, Value>* node); void flipColors(Node<Key, Value>* node); bool isRed(Node<Key, Value>* node); Node<Key, Value>* add(Node<Key, Value>* root, const Key &k, const Value &v); private: int _size; Node<Key, Value> *_root; }; #endif // __RBTREE_HPP ```