RBTree(紅黑樹)
阿新 • • 發佈:2019-02-11
#include <math.h> #include <iostream> using namespace std; enum colour { BLACK, RED, }; template<class K, class V> struct RBTreeNode { K _key; V _val; colour _col; RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; int _bf; RBTreeNode(const K& key, const V& value) :_left(NULL) , _right(NULL) , _parent(NULL) , _key(key) , _val(value) , _bf(0) , _col(RED) {} }; 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* parent = NULL; Node* cur = _root; while (cur) { if (cur->_key < key)//右邊 { parent = cur; cur = cur->_right; } else if (cur->_key>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; } while (parent && parent->_col==RED) { Node* grandparent = parent->_parent; if (grandparent->_left==parent) //父親在左邊 { Node* uncle = grandparent->_right; if (uncle&&uncle->_col==RED) { parent->_col = BLACK; uncle->_col = BLACK; grandparent->_col = RED; cur = grandparent; //向上調整 parent = cur->_parent; // } else //叔叔不存在或者叔叔為黑,需要旋轉 { if (cur==parent->_right) { RotateL(parent); swap(parent,cur); } RotateR(grandparent); parent->_col = BLACK; grandparent->_col = RED; break; } } else //parent = grandparent->_right; { Node* uncle = grandparent->_left; if (uncle&&uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandparent->_col = RED; cur = grandparent; //向上調整 parent = cur->_parent; // } else //叔叔不存在或者叔叔為黑,需要旋轉 { if (cur == parent->_left) { RotateR(parent); swap(parent, cur); // 若cur在parent的左,cur->_key < parent->_key,旋轉後必須交換才符合_key值得排布規則。 } RotateL(grandparent); parent->_col = BLACK; grandparent->_col = RED; } } } _root->_col = BLACK; return true; } bool Isbalance() { if (_root==NULL) { return true; } if (_root->_col==RED) { return false; } int Blacknum = 0; Node* left = _root; while (left) //遍歷任意一邊,計算出黑色節點的個數,作為一個基準,將此數與其他路上的書做較,只要不相等就可以說明此樹不是平衡紅黑樹 { if (left->_col==BLACK) { Blacknum++; } left = left->_left; } int num = 0; return _IsBalance(_root, Blacknum, num); } bool _IsBalance(Node* root, const int Blacknum, int num) { if (root == NULL) { if (num != Blacknum) { cout << "黑節點個數不等" << endl; return false; } else { return true; } } if (root->_col == BLACK) { num++; } if ((root->_col == RED) && (root->_parent->_col == RED)) { cout << root->_key << " " << root->_parent->_key << " " << endl; return false; } return _IsBalance(root->_left, Blacknum, num) && _IsBalance(root->_right, Blacknum, num); } 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; Node* ppnode = parent->_parent; parent->_parent = subR;///////////////// if (ppnode == NULL) { _root = subR; subR->_parent = NULL; } else if (parent == ppnode->_left) { ppnode->_left = subR; } else { ppnode->_right = subR; } subR->_parent = ppnode; } void RotateR(Node* parent) { Node* subL = parent->_left; Node* subLR = subL->_right; parent->_left = subLR; if (subLR) { subLR->_parent = parent; } subL->_right = parent; subL->_parent = parent->_parent; Node* ppnode = parent->_parent; parent->_parent = subL; if (ppnode == NULL) { _root = subL; subL->_parent = NULL; } else if (ppnode->_left == parent) { ppnode->_left = subL; } else { ppnode->_right = subL; } subL->_parent = ppnode; } void InOrder() { _InOrder(_root); cout << endl; } protected: void _InOrder(Node* root) { if (root == NULL) { return; } _InOrder(root->_left); cout << root->_key << " "; _InOrder(root->_right); } private: Node* _root; }; void Test() { int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 }; //int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 }; //int a[] = {2,3,1,4,5}; //int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; RBTree<int, int> t; for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); i++) { //t.Insert(a[i], i); t.Insert(a[i],i); cout << t.Isbalance()<< endl; } t.InOrder(); }