一.概念
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。
2.性质:
每个节点,不是红色就是黑色的
根节点是黑色的
如果一个节点是红色的,则它的两个子节点是黑色的(没有连续的红节点)
对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。(每条路径的黑色节点的数量相等)
二.代码实现
#include<iostream> using namespace std; enum COL { RED, BLACK }; template<class K, class V> struct RBTreeNode { K _key; V _value; COL _col; RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; RBTreeNode(const K& key,const V& value) : _key(key) , _value(value) , _col(RED) , _left(NULL) , _right(NULL) , _parent(NULL) {} }; template<class K,class V> class RBTree { typedef RBTreeNode<K, V> Node; public: RBTree() :_root(NULL) {} ~RBTree() {} bool Insert(const K& key, const V& value) { //寻找插入节点的位置 if (_root == NULL) { _root = new Node(key, value); _root->_col = BLACK; return true; } Node* cur = _root; Node* parent = NULL; while (cur) { if (key > cur->_key) { parent = cur; cur = cur->_right; } else if (key < cur->_key) { parent = cur; cur = cur->_left; } else { return false; } } //插入 cur = new Node(key, value); if (key > parent->_key) { parent->_right = cur; cur->_parent = parent; } else { parent->_left = cur; cur->_parent = parent; } //判断是否符合红黑树 //判断规则3(不能有连续的两个红节点) while (cur != _root&&parent->_col==RED)//cur!=_root保证了parent不为空 { Node* Grandparent = parent->_parent; //找叔叔节点 if (Grandparent->_left == parent) { Node* uncle = Grandparent->_right; //第一种情况:叔叔节点存在且为红 if (uncle&&uncle->_col == RED) { //将parent和uncle变黑,grandparent变红,再把cur赋值给grandparent,向上调整 parent->_col = uncle->_col = BLACK; Grandparent->_col = RED; cur = Grandparent; parent = cur->_parent; } //第二种情况:叔叔节点不存在或为黑(此时grandparent、parent、cur构成了单旋的条件) else { //第三种情况:此时grandparent、parent、cur构成了双旋的条件 if (parent->_right == cur) { //对parent做左单旋,转换为第二种情况 RotateL(parent); //注意:旋转后指针位置需交换 swap(parent, cur); } RotateR(Grandparent); //将parent变黑,grandparent变红 parent->_col = BLACK; Grandparent->_col = RED; break; } } //和上面相反 else { Node* uncle = Grandparent->_left; //第一种情况 if (uncle&&uncle->_col == RED) { parent->_col = uncle->_col = BLACK; Grandparent->_col = RED; cur = Grandparent; parent = cur->_parent; } //第二种情况 else { //第三种情况 转换为第二种情况 if (parent->_left == cur) { RotateR(parent); swap(parent, cur); } RotateL(Grandparent); parent->_col = BLACK; Grandparent->_col = RED; break; } } } _root->_col = BLACK; return true; } void InOrder() { _InOrder(_root); cout << endl; } bool IsBlance() { if (_root == NULL) return true; //第2条规则:根节点是黑色的 //判断根节点 if (_root->_col == RED) { return false; } Node* cur = _root; int k = 0; while (cur) { //第4条规则:每条路径的黑色节点的数量相等 //统计每个左右子树黑色节点的个数 if (cur->_col == BLACK) { k++; } cur = cur->_left; } int count = 0; return _IsBlance(_root,k,count); } protected: Node* _root; void _InOrder(Node* root) { if (root == NULL) return; _InOrder(root->_left); cout << root->_key << " "; _InOrder(root->_right); } bool _IsBlance(Node* root,const int k,int count) { if (root == NULL) return true; //第3条规则:没有连续的红节点 if (root->_col == RED) { if (root->_parent->_col == RED) { cout << "颜色不对" << root->_key << endl; return false; } } //统计黑色节点 else { ++count; } if (root->_left == NULL&&root->_right) { if (count == k) return true; else { cout << "黑色节点数量不相同" << root->_key << endl; return false; } } return _IsBlance(root->_left, k, count) && _IsBlance(root->_right, k, count); } void RotateL(Node* parent) { Node* subR = parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if (subRL) { subRL->_parent = parent; } Node* ppNode = parent->_parent; subR->_left = parent; parent->_parent = subR; if (ppNode == NULL) { _root = subR; subR->_parent = NULL; } else { subR->_parent = ppNode; if (ppNode->_left == parent) { ppNode->_left = subR; } else { ppNode->_right = subR; } } } void RotateR(Node* parent) { Node* subL = parent->_left; Node* subLR = subL->_right; parent->_left = subLR; if (subLR) { subLR->_parent = parent; } Node* ppNode = parent->_parent; subL->_right = parent; parent->_parent = subL; if (ppNode == NULL) { _root = subL; subL->_parent = NULL; } else { subL->_parent = ppNode; if (ppNode->_left == parent) { ppNode->_left = subL; } else { ppNode->_right = subL; } } } }; int main() { int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; RBTree<int, int> rbt; for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { rbt.Insert(a[i],i); cout <<a[i]<< " Is Blance ?" << rbt.IsBlance() << endl; } rbt.InOrder(); cout<<"Is Blance ?"<<rbt.IsBlance()<<endl; system("pause"); return 0; }
本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1828120
原文地址:http://10707460.blog.51cto.com/10697460/1828120