红黑树
来源:互联网 发布:淘宝手游充值 编辑:程序博客网 时间:2024/05/16 12:20
当我们在使用二叉搜索树时,如果树的高度较高,对其的操作并不比对链表操作要快。原因是二叉搜索树在插入顺序基本有序时会退化为一个排序链表,所以说是不平衡的。
对二叉搜索树的改进有AVL树和红黑树。先来看红黑树,它广泛应用在STL的set和map,Java库和Linux内核等中 。
红黑树是一颗平衡的二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是RED或BLANK。通过对任何一条从根节点到叶子节点的简单路径上各个节点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出2倍,因而是近似平衡的。
红黑树的约束如下:
- 每个节点要么是红色的,要么是黑色的;
- 根节点是黑色的;
- 如果一个节点是红色的,那么它的两个子节点都是黑色的;
- 对每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含数目相同的黑色节点;
每个叶子节点是黑色的(这里的叶子节点指的是NIL节点,即空节点)。
红黑树的插入操作步骤如下:
- 先按照搜索树的步骤将节点插入到相应位置,并置该节点颜色为红色。设该节点指针为cur;
- 如果破坏了以上某些条件,则对该树进行相应的调整,步骤如下:
- 情况1:若cur的父亲结点和叔叔节点都为红色,则进行红色提升;
- 情况2:若父红叔黑或叔叔不存在,且cur为其父节点的右孩子,则令cur=parent并以父节点为根进行旋转;
- 情况3:若父红叔黑或叔叔不存在,且cur为其父节点的左孩子,则将父节点变为黑色,祖父节点变为红色并以祖父节点为根进行旋转;
代码如下:
#pragma once#include<iostream>using namespace std;enum Color{ RED, BLANK,};template<typename K,typename V>struct RBTreeNode{ K _key; V _value; RBTreeNode<K,V>* _left; RBTreeNode<K,V>* _right; RBTreeNode<K,V>* _parent; Color _color; RBTreeNode(const K& key=K(),const V& value=V()) :_key(key),_value(value) ,_left(NULL),_right(NULL) ,_parent(NULL) ,_color(RED) {}};template<typename K,typename V>class RBTree{ typedef RBTreeNode<K,V> Node;public: RBTree() :_root(nil) {} bool Insert(const K& key,const V& value) { Node* s=new Node(key,value); Node* parent=nil; Node* cur=_root; while(cur!=nil) { parent=cur; if(cur->_key>cur->_key) cur=cur->_left; else cur=cur->_right; } cur->_parent=parent; if(parent==nil) _root=s; else if(s->_key>parent->_key) parent->_right=s; else parent->_left=s; s->_left=s->_right=nil; //s->_color=RED; RB_INSERT_FIX(s); } bool Remove(const K& key); Node* Find(const K& key); bool IsBalance();protected: void RotateL(Node* root) { if(root==NULL) return; Node* parent=root; Node* subR=parent->_right; Node* subRL=subR->_left; parent->_right=subRL; if(subRL!=NULL) subRL->_parent=parent; Node* ppNode=parent->_parent; subR->_left=parent; parent->_parent=subR; if(ppNode!=NULL) { if(ppNode->_left==parent) ppNode->_left=subR; else ppNode->_right=subR; } else { _root=subR; } subR->_parent=ppNode; parent->_bf = subR->_bf = 0; } void RotateR(Node* root) { if(root==NULL) return; Node* parent=root; Node* subL=parent->_left; Node* subLR=subL->_right; parent->_left=subLR; if(subLR!=NULL) subLR->_parent=parent; Node* ppNode=parent->_parent; subL->_right=parent; parent->_parent=subL; if(ppNode!=NULL) { if(ppNode->_left==parent) ppNode->_left=subL; else ppNode->_right=subL; } else { _root=subL; } subL->_parent=ppNode; parent->_bf = subL->_bf = 0; } void RB_INSERT_FIX(Node* cur) { while(cur->_parent._color==RED) { Node* parent=cur->_parent; Node* grandfather=parent->_parent; Node* uncle; if(parent=grandfather->_left) { uncle=grandfather->_right; if(uncle->_color=RED) { parent->_color=BLANK; uncle->_color=BLANK; grandfather->_color=RED; cur=grandfather; } else if(cur=parent->_right) { cur=parent; rotateL(cur); } else { parent->_color=BLANK; grandfather->_color=RED; rotateR(grandfather); } } else { uncle=grandfather->_left; if(uncle->_color=RED) { parent->_color=BLANK; uncle->_color=BLANK; grandfather->_color=RED; cur=grandfather; } else if(cur=parent->_left) { cur=parent; rotateR(cur); } else { parent->_color=BLANK; grandfather->_color=RED; rotateL(grandfather); } } } _root->_color=BLANK; }private: Node* _root; static Node* nil;};template<typename K,typename V>RBTreeNode<K,V>* RBTree<K,V>::nil=new RBTreeNode<K,V>();
以上
如果你有任何想法或是可以改进的地方,欢迎和我交流!
完整代码在github上:点我前往
本文首发于www.sbrave.cn
【完】
0 0
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- C++对象模型的那些事儿之四:拷贝构造函数
- CSS样式表的优先级
- hadoop配置文件详解
- 使用jquery动态往table添加tr
- onethink的后台登录验证码突然一直提示错误
- 红黑树
- C++对象模型的那些事儿之五:NRV优化和初始化列表
- Android设计模式——Builder模式 -- 助于理解所有 类似NotificationCompat.Builder [*.Builder] 模式调用
- HashSet、HashMap、ArrayList、LinkedList、Vector区别
- linux ls -l 详解
- POJ3080——Blue Jeans
- C++对象模型的那些事儿之六:成员函数调用方式
- About
- SDUT1047Color Me Less