标签:红黑树
红黑树特性:
1、节点颜色非黑即红
2、根节点颜色一定是黑色
3、某一节点到其任意叶节点的路径中黑结点数量相等(保证了这颗树最长路径长度不超过最短路径的2倍)
4、不能有连续的两个红节点
#ifndef __RBTREE__ #define __RBTREE__ #include <iostream> #include <stack> //节点颜色,非黑即红 enum colour{ RED, BLACK }; //节点数据结构 template<class K> struct RBTreeNode { typedef RBTreeNode<K>* Node_p; Node_p _left; Node_p _right; Node_p _parent; K _key; colour _colour; RBTreeNode(const K& key = K()) :_left(NULL) , _right(NULL) , _parent(NULL) , _key(key) , _colour(RED) {} }; //红黑树结构 template<class K> class RBTree { typedef RBTreeNode<K> Node; typedef Node* Node_p; public: RBTree() :_root(NULL) {} std::pair<Node_p, bool> Find(K key) { if (_root == NULL){ return std::pair<Node_p, bool>(NULL, false); } Node_p cur = _root; Node_p parent = NULL; while (cur){ if (cur->_key == key) return std::pair<Node_p, bool>(cur, true); else if (key < cur->_key){ parent = cur; cur = cur->_left; } else{ parent = cur; cur = cur->_right; } } return std::pair<Node_p, bool>(parent, false); } bool Insert(K key) { if (_root == NULL){//空树 _root = new Node(key); _root->_colour = BLACK; return true; } std::pair<Node_p, bool> ret = Find(key); if (ret.second)//找到了键为key的节点,无法插入 return false; Node_p parent = ret.first; Node_p Grandparent = parent->_parent; Node_p cur; Node_p GGrandparent; _Insert(parent,key); if (parent->_colour == BLACK) return true; //祖父节点Grandparent一定存在 if (key < parent->_key){ cur = parent->_left; } else{ cur = parent->_right; } //***********************以上插入成功 //***********************以下判断是否需要旋转变色 Node_p Uncle; while (Grandparent){ if (parent == Grandparent->_left) Uncle = Grandparent->_right; else Uncle = Grandparent->_left; GGrandparent = Grandparent->_parent; if (Uncle == NULL || Uncle->_colour == BLACK){//Grandparent一定为黑,旋转之后也一定为黑 if (parent == Grandparent->_left){ if (parent->_right == cur){//U为黑,cur内插,把cur转换为外插 _RotateL(parent); std::swap(parent,cur); } _RotateR(Grandparent); parent->_colour = BLACK; Grandparent->_colour = RED; } else{ if (parent->_left == cur){//U为黑,cur内插,把cur转换为外插 _RotateR(parent); std::swap(parent, cur); } _RotateL(Grandparent); parent->_colour = BLACK; Grandparent->_colour = RED; } break; } else if (Uncle->_colour == RED){//Grandparent一定为黑,旋转之后为红 if (parent == Grandparent->_left){ if (parent->_right == cur){//U为红,cur内插,转为外插 _RotateL(parent); std::swap(parent, cur); } _RotateR(Grandparent); cur->_colour = BLACK; } else{ if (parent-> _left == cur){//U为红,cur内插 _RotateR(parent); std::swap(parent, cur); } _RotateL(Grandparent); cur->_colour = BLACK; } if (GGrandparent && GGrandparent->_colour == RED){ cur = parent ; parent = cur->_parent; Grandparent = parent->_parent; } else break; } } _root->_colour = BLACK; return true; } void InOrder() { _InOrder(_root); std::cout << std::endl; } void InOrder_Non_R() { std::stack<Node_p> s; Node_p cur = _root; while (cur || !s.empty() ){ while (cur){ s.push(cur); cur = cur->_left; } Node_p tmp=s.top(); s.pop(); std::cout << tmp->_key<<" "; cur = tmp->_right; } std::cout << std::endl; } bool Is_Balance() {} private: void _Insert(Node_p cur,K& key) { Node_p tmp = new Node(key); if (key < cur->_key){ cur->_left = tmp; } else{ cur->_right = tmp; } tmp->_parent = cur; } //左旋 void _RotateL(Node_p parent) { Node_p subR = parent->_right; Node_p subRL = subR->_left; parent->_right = subRL; if (subRL) subRL->_parent = parent; subR->_left = parent; Node_p ppNode = parent->_parent; parent->_parent = subR; if (ppNode){ if (ppNode->_left == parent) ppNode->_left = subR; else ppNode->_right = subR; subR->_parent = ppNode; } else{ _root = subR; subR->_parent = NULL; } } //右旋 void _RotateR(Node_p parent) { Node_p subL = parent->_left; Node_p subLR = subL->_right; parent->_left = subLR; if (subLR) subLR->_parent = parent; Node_p ppNode = parent->_parent; subL->_right = parent; parent->_parent = subL; if (ppNode){ if (ppNode->_left == parent) ppNode->_left = subL; else ppNode->_right = subL; subL->_parent = ppNode; } else{ _root = subL; subL->_parent = NULL; } } void _InOrder(Node_p root) { if (root == NULL) return; _InOrder(root->_left); std::cout << root->_key << " "; _InOrder(root->_right); } protected: Node_p _root; size_t _node_count;//记录结点数量 }; #endif
本文出自 “零蛋蛋” 博客,谢绝转载!
标签:红黑树
原文地址:http://lingdandan.blog.51cto.com/10697032/1837331