RBTree(红黑树)--C++
2016-05-07 15:05
387 查看
红黑树是满足下面性质的二叉搜索树
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
#pragma once enum Color{ RED, BLACK }; template<class K, class V> struct RBtreeNode { RBtreeNode(const K& key, const V& v, Color col = RED) :_left(NULL) , _right(NULL) , _parent(NULL) , _key(key) , _vlaue(v) , _col(col) {} RBtreeNode<K, V>* _left; RBtreeNode<K, V>* _right; RBtreeNode<K, V>* _parent; K _key; V _vlaue; Color _col; }; template<class K, class V> class RBtree { typedef RBtreeNode<K, V> Node; public: RBtree() :_root(NULL) {} bool Insert(const K& key, const V& v) { if (_root == NULL) { _root = new Node(key, v, BLACK); return true; } Node* parent = NULL; Node* cur = _root; while (cur) { if (key < cur->_key) { parent = cur; cur = cur->_left; } else if (key > cur->_key) { parent = cur; cur = cur->_right; } else { return false; } } cur = new Node(key, v, RED); if (key < parent->_key) { parent->_left = cur; cur->_parent = parent; } else { parent->_right = cur; cur->_parent = parent; } //调色 while (cur != _root && parent->_col == RED) { Node* GrandParent = parent->_parent; if (parent == GrandParent->_left)//往左子树插 { Node* uncle = GrandParent->_right; if (uncle && uncle->_col == RED) { uncle->_col = parent->_col = BLACK; GrandParent->_col = RED; cur = GrandParent; parent = cur->_parent; } else { if (cur == parent->_right) { _RotateL(parent); swap(cur, parent); } _RotateR(GrandParent); parent->_col = BLACK; GrandParent->_col = RED; } } else//往右子树插 { Node*uncle = GrandParent->_left; if (uncle && uncle->_col == RED) { uncle->_col = parent->_col = BLACK; GrandParent->_col = RED; cur = GrandParent; parent = cur->_parent; } else { if (cur == parent->_left) { _RotateR(parent); swap(cur, parent); } _RotateL(GrandParent); parent->_col = BLACK; GrandParent->_col = RED; } } } _root->_col = BLACK; return true; } bool IsBalanceTree() { return _IsBalance(_root); } void InOrder() { _InOrder(_root); cout << endl; } protected: int _Height(Node* root) { if (root == NULL) { return 0; } int left = _Height(root->_left) + 1; int right = _Height(root->_right) + 1; return (left > right) ? left : right; } bool _IsBalance(Node* root) { if (root == NULL) { return true; } int left = _Height(root->_left); int right = _Height(root->_right); int bf = abs(left - right); if (bf > 1) { return false; } return _IsBalance(root->_left) && _IsBalance(root->_right); } void _RotateL(Node* parent) { Node *subR = parent->_right; Node *subRL = subR->_left; parent->_right = subRL; if (subRL) { subRL->_parent = parent; } subR->_left = parent; subR->_parent = parent->_parent; parent->_parent = subR; parent = subR; //连爸爸:) if (parent->_parent == NULL) { _root = parent; } else { if (parent->_parent->_key < parent->_key) { parent->_parent->_right = parent; } else { parent->_parent->_left = parent; } } } void _RotateR(Node* parent) { Node *subL = parent->_left; Node *subLR = subL->_right; parent->_left = subLR; if (subLR != NULL) { subLR->_parent = parent; } subL->_right = parent; subL->_parent = parent->_parent; parent->_parent = subL; parent = subL; if (parent->_parent == NULL) { _root = parent; } else { if (parent->_parent->_key < parent->_key) { parent->_parent->_right = parent; } else { parent->_parent->_left = parent; } } } void _InOrder(Node*& root) { if (root == NULL) { return; } _InOrder(root->_left); cout << root->_key << " "; _InOrder(root->_right); } protected: Node* _root; }; void TestRBTree1() { RBtree<int, int> t1; int a[10] = { 5, 2, 9, 6, 7, 3, 4, 0, 1, 8 }; for (size_t i = 0; i < sizeof(a) / sizeof(int); ++i) { t1.Insert(a[i], i); t1.InOrder(); } cout << "IsBalanceTree ? "<< t1.IsBalanceTree() << endl; }
相关文章推荐
- window.parent与window.openner区别介绍
- JQuery.closest(),parent(),parents()寻找父结点
- jQuery的:parent选择器定义和用法
- jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
- php实现parent调用父类的构造方法与被覆写的方法
- jQuery中parents()和parent()的区别分析
- JS window对象的top、parent、opener含义介绍
- Android 不能返回 parent Activity 的问题
- 《Parent Effectiveness Training》--简介
- jquery中closet,parent,parents
- Firebug报错: TypeError: parent.XXX is undefined 解决方法
- 类的继承(extends)与重载(parent::)
- Jquery一些有用的但是不是经常使用的方法和属性
- php类中 self parent static的区别
- 【笔记】 《js权威指南》- 第14章 Window对象 14.8 多窗口和窗体
- 命名空间函数用法及例子
- Qt学习之parent参数
- 如何让ScrollView充满整个屏幕
- jquery遍历之parent()与parents()的区别 及 parentsUntil() 方法
- JS调用iframe父窗口元素和子窗口元素的方法