紅黑樹
紅黑樹也是二叉搜索樹,只是每個結點增加顏色表示。
紅黑樹有以下規則:
每個結點不是red就是black
根結點爲black
若結點爲red,則它的兩個子節點爲black
從每一條路徑(根到葉)均有相同數目的black
*紅黑樹保證最長路徑不超過最短路徑的兩倍
二叉樹在插入時的幾種需要轉換的情況:
情況1
情況2
情況3:
代碼實現;
enum color { RED, BLACK, }; template<class K,class V> struct RBTreeNode { K _key; V _value; RBTreeNode<K, V> *_left; RBTreeNode<K, V> * _right; RBTreeNode<K, V> * _parent; color _col; RBTreeNode(const K&key,const V&value) :_key(key) , _value(value) , _left(NULL) , _right(NULL) , _parent(NULL) , _col(RED) {} }; template<class K,class V> class RBTree { public: RBTree() :_root(NULL) {} bool Insert(const K& key, const V& value) { if (_root == NULL) { _root = new RBTreeNode<K, V>(key, value); _root->_col = BLACK; return true; } RBTreeNode<K, V>* parent = NULL; RBTreeNode<K, V>* cur = _root; while (cur)//找到要插入的位置 { parent = cur; if (key > cur->_key) { cur = cur->_right; } else if (key < cur->_key) { cur = cur->_left; } else return false; } cur = new RBTreeNode<K, V>(key, value); if (parent->_key>key) { parent->_left=cur; cur->_parent = parent; } else { parent->_right = cur; cur->_parent = parent; } while (cur != _root&&parent->_col == RED)//cur!=_root則父節點一定存在,若父節點的顏色爲red則一定不是根結點 { RBTreeNode<K, V> *grandfather = parent->_parent; if (grandfather->_left == parent) { RBTreeNode<K, V>*uncle = grandfather->_right; if (uncle&&uncle->_col == RED) { //情況1 parent->_col = BLACK; uncle->_col = BLACK; grandfather->_col = RED; cur = grandfather; parent = cur->_parent; } else//情況2和情況3 { if (parent->_right==cur) { _RotateL(parent); swap(cur, parent); } parent->_col = BLACK; grandfather->_col = RED; _RotateR(grandfather); } } else { RBTreeNode<K, V>*uncle = grandfather->_left; if (uncle&&uncle->_col == RED) { uncle->_col = BLACK; parent->_col = BLACK; grandfather->_col = RED; cur = grandfather; parent = cur->_parent; } else { if (cur == parent->_left) { _RotateR(parent); parent->_col = BLACK; grandfather->_col = RED; _RotateL(grandfather); } _root->_col = BLACK; return true; } } } _root->_col = BLACK; return true; } void Inorder() { _Inorder(_root); cout << endl; } protected: void _Inorder(RBTreeNode<K, V>*root) { if (root == NULL) return; _Inorder(root->_left); cout << _root->_key << " "; _Inorder(_root->_right); } void _RotateL(RBTreeNode<K, V>*parent) { RBTreeNode<K, V>*subR = parent->_right; RBTreeNode<K, V>*subRL = subR->_left; parent->_right = subRL; if (subRL != NULL) subRL->_parent = parent; subR->_left= parent; RBTreeNode<K, V>*ppNode = parent->_parent; parent->_parent = subR; subR->_parent = ppNode; if (ppNode == NULL) { _root = subR; } else { if (ppNode->_left == parent) ppNode->_left = subR; else ppNode->_right = subR; } } void _RotateR(RBTreeNode<K, V>*parent) { RBTreeNode<K, V>*subL = parent->_left; RBTreeNode<K, V>*subLR = subL->_right; parent->_left = subLR; if (subLR != NULL) subLR->_parent = parent; subL->_right = parent; RBTreeNode<K, V>*ppNode = parent->_parent; parent->_parent = subL; subL->_parent = ppNode; if (ppNode == NULL) _root = subL; else { if (ppNode->_left == parent) ppNode->_left = subL; else ppNode->_right = subL; } } private: RBTreeNode<K, V> *_root; };