红黑树实现

来源:互联网 发布:win7 for mac 安装iso 编辑:程序博客网 时间:2024/05/22 04:51

  1.红黑树的由来

     红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数数据结构,典型的用途是实现关联数组。

它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。

红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除。

2.红黑树的性质

  红黑树首先是一颗二叉查找树,它的每个结点要么是红色,要么是黑色,它满足个性质:

 1,每个结点要么是红色,要么是黑色。
 2,根结点是黑色。
 3,叶子结点看作黑色结点,同时也被叫做黑哨兵。
 4,任何一条路径上不可能出现相邻两个红色结点,即每个红色结点都有两个黑色子结点。
 5,任何结点到其子孙结点所有路径上有相同数量的黑色结点。

3.红黑树的插入,当然每个结点初始为红色

   1,如果红黑树为空,即插入结点为根结点,把结点变为黑色即可。
   2,如果插入结点父结点为黑,直接插入。

3,如果插入结点的父结点为红色,则其祖父结点必为黑色,此时较为复杂。由其叔叔结点决定进一步操作。


3.1 当叔结点为红色,则把父结点,叔结点变为黑色,祖父结点变为红色。以祖父结点作为新结点向上进行平衡操作。


需要注意的是无论结点叔是祖父结点的左孩子还是右孩子,调整都一样。

3.2当叔结点是黑色时,则进行旋转操作,有以下情况:
 
情况1:
         

        


情况2:



情况3:当父结点为祖父结点的左孩子,且新插入结点为父结点的左孩子时进行左旋转,和情况1类似,只是旋转方向不同而已。



情况4:当父结点为祖父结点的左孩子时,且新插入结点为父结点的右孩子时,先右旋转,后左旋,和情况2类似。


到此红黑树插入调整的各种情况介绍结束,其实插入并不难,但是红黑树的删除比AVL树复杂的多。


4,红黑树的删除

     红黑树的删除比较复杂,当然先把结点按照二叉搜索树方法删除,然后再调整。二叉搜索树的删除有复制删除和合并删除,复制删除较为重用。采用复制删除,结合红黑树的特点,有以下情况。

  情况1:真正删除的结点必定是只有一个红色孩子的结点或者是叶结点;

  情况2:如果真正删除的结点是 一个红色的结点,那么这个结点一定是叶子。

以下讨论删除的各种情况,当结点被标注为“旧”时表示真正被删除的结点,新结点表示删除后代替结点。


1,当红黑树只有一个结点时,即只有根结点,那么直接删除,完成。


2,当删除结点为红色时,直接删除,因为不影响红黑树的性质。


3,当真正删除结点有一个红色孩子,删除时把被删除点红色孩子变为黑色即可。

4,当删除结点为叶子且为黑色时,由于是黑色的叶结点,则必有兄弟结点,此时情况比较复杂,有以下情况。

 

情况1:当被删除结点的兄弟为红色时,由于兄弟结点是红色,则父结点必为黑色,首先可以进行旋转操作后再进行调整。


当然,如果兄结点为右孩子,则进行右旋转,然后以新结点进行调整。从变化来看都是经过旋转后把兄弟结点变为黑色,父结点变为红色。


情况2:当被删除结点兄弟结点为黑色时,且父结点为红色时,此时直接把父结点变为黑色,兄弟结点变为红色




如果兄弟结点为右孩子,则一样,把父结点变为黑色,兄弟结点变为红色。


情况3:兄弟结点为黑色,父结点也为黑色,则把兄弟结点变为红色即可。


情况4:如果有红色的侄出现,则进行以下变化。


 4.4.1


4.4.2


4.4.3如果出现右兄右侄时则进行左旋,同时把兄弟结点变为父结点颜色,同时把父结点,侄子结点变为黑色。与4.4.1相似。


4.4.3如果出现右兄左侄,则先进行右旋,后进行左旋,同时把兄弟结点和父结点变为黑色,侄子结点变为与新结点的父结点相同的颜色。与4.4.2相似。


5 源码

#include<iostream>#include<ctime>using namespace std;typedef  bool red;#define RED 1#define BLACK 0template<class T>class RB_tree_node{public:T data;RB_tree_node<T> *parent;RB_tree_node<T> *leftChild;RB_tree_node<T> *rightChild;red red_node;RB_tree_node();RB_tree_node(T item);};template<class T>class RB_tree{private:RB_tree_node<T> *root;public:RB_tree();~RB_tree();RB_tree_node<T>* search(T &data);void Insert(T data);void Delete(T data);void DeleteFixup(RB_tree_node<T> *old_node);void Inorder();void resverse(RB_tree_node<T> *node);void free(RB_tree_node<T> *t);void show(RB_tree_node<T> *rb){cout << rb->data << " " << rb->red_node << endl;}};template<class T>class stack{private:int maxSize;int top;T *atr;public:stack(int szie = 0);~stack();bool IsEmpty();bool IsFull();bool pop(T& item);bool push(T&item);void clear();T GetTop();};template<class T>stack<T>::stack(int size){maxSize = size;top = -1;atr = new T[maxSize];}template<class T>stack<T>::~stack(){delete[]atr;}template<class T>bool stack<T>::IsEmpty(){return top == -1;}template<class T>bool stack<T>::IsFull(){return top == maxSize - 1;}template<class T>bool stack<T>::pop(T &item){if (top == -1){cout << "error" << endl;return false;}else{item = atr[top--];return true;}}template<class T>bool stack<T>::push(T &item){if (top == maxSize - 1){cout << "error" << endl;return false;}else{atr[++top] = item;return true;}}template<class T>T stack<T>::GetTop(){return  atr[top];}template<class T>RB_tree_node<T>::RB_tree_node(){data = 0;leftChild = NULL;rightChild = NULL;parent = NULL;red_node = RED;}template<class T>RB_tree_node<T>::RB_tree_node(T item){data = item;leftChild = NULL;rightChild = NULL;parent = NULL;red_node =RED;}template<class T>RB_tree<T>::RB_tree(){root = NULL;}template<class T>RB_tree<T>::~RB_tree(){free(root);}template<class T>RB_tree_node<T>* RB_tree<T>::search(T &data){RB_tree_node<T> *p = root;while (p){if (p->data == data)break;else{if (p->data > data)p = p->leftChild;else{p = p->rightChild;}}}return p;}template<class T>void RB_tree<T>::Insert(T data){RB_tree_node<T> *rb_node = new RB_tree_node<T>(data),*pre=root,*current=root;if (root == NULL){root = rb_node;}else{current = pre = root;while (current){pre=current;if (current->data > data){current= current->leftChild;}else{current = current->rightChild;}}if (data < pre->data){pre->leftChild = rb_node;rb_node->parent = pre;}else{pre->rightChild = rb_node;rb_node->parent = pre;}}resverse(rb_node);}template<class T>void RB_tree<T>::resverse(RB_tree_node<T>*node){RB_tree_node<T> *node_parent,*node_grend;while (1){node_parent = node->parent;if (!node)break;else if (node_parent == NULL){node->red_node = BLACK;break;}else if(node_parent&&node_parent->red_node==BLACK){break;}else if (node_parent->red_node==RED){node_grend = node_parent->parent;if (node_grend->leftChild == node_parent){if (node_grend->rightChild&&node_grend->rightChild->red_node == RED){node_grend->red_node = RED;node_parent->red_node = BLACK;node_grend->rightChild->red_node = BLACK;node = node_grend;}else{if (node_parent->rightChild == node){if (node->leftChild){node->leftChild->parent = node_parent;node_parent->rightChild = node->leftChild;}else{node_parent->rightChild = NULL;}node->parent = node_parent->parent;node_parent->parent->leftChild = node;node->leftChild = node_parent;node_parent->parent = node;node_parent = node->parent;node_grend = node_parent->parent;}else{node_grend = node_grend->parent;node_parent = node_parent->parent;node = node->parent;}if (node->rightChild){node->rightChild->parent = node_parent;node_parent->leftChild = node->rightChild;}else{node_parent->leftChild = NULL;}if (node_grend){if (node_grend->leftChild == node_parent){                            node_grend->leftChild = node;}else{node_grend->rightChild = node;}node->parent = node_grend;}else{                        node->parent = NULL;root = node;}node->rightChild = node_parent;node_parent->parent = node;node->red_node = BLACK;node->rightChild->red_node = RED;break;}}else{if (node_grend->leftChild&&node_grend->leftChild->red_node == RED){node_grend->red_node = RED;node_parent->red_node = BLACK;node_grend->leftChild->red_node = BLACK;node = node_grend;}else{if (node->parent->leftChild == node){if (node->rightChild){node->rightChild->parent = node_parent;node_parent->leftChild = node->rightChild;}else{node_parent->leftChild = NULL;}node->parent = node_parent->parent;node->parent->rightChild = node;node_parent->parent = node;node->rightChild = node_parent;node_parent = node->parent;node_grend = node_parent->parent;}else{node_grend = node_grend->parent;node_parent = node_parent->parent;node = node->parent;}if (node->leftChild){node->leftChild->parent = node_parent;node_parent->rightChild = node->leftChild;}else{node_parent->rightChild = NULL;}if (node_grend){if (node_grend->rightChild == node_parent){node_grend->rightChild = node;                         }                     else{node_grend->leftChild = node;}node->parent = node_grend;}else{                   node->parent = NULL;   root = node;}node_parent->parent = node;node->leftChild = node_parent;node->red_node = BLACK;node->leftChild->red_node = RED;break;}}}}}template<class T>void RB_tree<T>::free(RB_tree_node<T> *t){if (t){free(t->leftChild);free(t->rightChild);delete t;}}template<class T>void RB_tree<T>::Inorder(){stack<RB_tree_node<T> *> s(30);RB_tree_node<T> *ptr = root;while (!s.IsEmpty() || ptr){if (ptr){s.push(ptr);ptr = ptr->leftChild;}else{s.pop(ptr);cout << "(" << ptr->data << ",";if (ptr->red_node)cout << "red" << ")" << endl;elsecout << "black" << ")" << endl;ptr = ptr->rightChild;}}}template<class T>void RB_tree<T>::Delete(T data){RB_tree_node<T> *ptr = root,*current=root,*pre=root,*ptr_pre;while (current){if (current->data == data)break;else if (current->data > data){pre = current;current = current->leftChild;}else{pre = current;current = current->rightChild;}}if (!current->leftChild&&!current->rightChild){if (pre == current){root = NULL;}else{if (pre->leftChild == current)pre->leftChild = NULL;else{pre->rightChild = NULL;}}DeleteFixup(current);}else if (current->leftChild&&!current->rightChild){if (pre == current){root = current->leftChild;root->parent = NULL;}else{if (pre->leftChild == current){pre->leftChild = current->leftChild;current->leftChild->parent = pre;}else{pre->rightChild = current->leftChild;current->leftChild->parent = pre;}}DeleteFixup(current);}else if (current->rightChild&&!current->leftChild){if (pre == current){root = current->rightChild;root->parent = NULL;}else{if (pre->leftChild == current){pre->leftChild = current->rightChild;current->rightChild->parent = pre;}else{pre->rightChild = current->rightChild;current->rightChild->parent = pre;}}DeleteFixup(current);}else if (current->leftChild&¤t->rightChild){ptr_pre = ptr = current->rightChild;while (ptr->leftChild){ptr_pre = ptr;ptr = ptr->leftChild;}if (ptr == ptr_pre){current->data = ptr->data;current->rightChild = ptr->rightChild;if (ptr->rightChild){ptr->rightChild->parent = current;}}else{current->data = ptr->data;ptr_pre->leftChild = ptr->rightChild;if (ptr->rightChild){ptr->rightChild->parent = ptr_pre;}}DeleteFixup(ptr);}}template<class T>void RB_tree<T>::DeleteFixup(RB_tree_node<T> *old_node){RB_tree_node<T> *old_node_parent,*old_node_grend,*old_node_brother;while (1){if (old_node->red_node==RED){break;}else if (old_node->leftChild&&old_node->leftChild->red_node==RED||old_node->rightChild&&old_node->rightChild->red_node==RED){if (old_node->leftChild){old_node->leftChild->red_node = BLACK;}else{old_node->rightChild->red_node = BLACK;}break;}else{old_node_parent = old_node->parent;//parentold_node_grend = old_node_parent->parent;//grandfatherif (old_node->parent == NULL&&!old_node->leftChild&&!old_node->rightChild)//删除仅有根节点的树;{break;}   if (old_node_parent->rightChild){old_node_brother = old_node_parent->rightChild;if (old_node_parent->rightChild->red_node == RED){old_node_parent->red_node = RED;old_node_brother->red_node = BLACK;if (old_node_brother->leftChild){old_node_brother->leftChild->parent = old_node_parent;old_node_parent->rightChild = old_node_brother->leftChild;}else{old_node_parent->rightChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->leftChild == old_node_parent){old_node_grend->leftChild = old_node_brother;}else{old_node_grend->rightChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->leftChild = old_node_parent;}else if (old_node->parent->rightChild->red_node==BLACK){bool red_parent = old_node_parent->red_node == RED,b_brother_l = old_node_brother->leftChild && (old_node_brother->leftChild->red_node == BLACK),b_brother_r = old_node_brother->rightChild && (old_node_brother->rightChild->red_node == BLACK),null_brother_s = !old_node_brother->leftChild&&!old_node_brother->rightChild;if (red_parent && (null_brother_s || (b_brother_l&&b_brother_r))){old_node->parent->red_node = BLACK;old_node_brother->red_node = RED;break;}else if (!red_parent && (null_brother_s ||(b_brother_l&&b_brother_r))){old_node_brother->red_node = RED;break;}else if (old_node_brother->rightChild&&old_node_brother->rightChild->red_node == RED){old_node_brother->red_node = old_node_parent->red_node;old_node_parent->red_node = BLACK;old_node_brother->rightChild->red_node =BLACK;old_node_parent = old_node->parent;old_node_grend = old_node_parent->parent;if (old_node_brother->leftChild){old_node_brother->leftChild->parent= old_node_parent;old_node_parent->rightChild = old_node_brother->leftChild;}else{old_node_parent->rightChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->leftChild==old_node_parent){old_node_grend->leftChild = old_node_brother;}else{old_node_grend->rightChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->leftChild = old_node_parent;break;}else if (old_node_brother->leftChild&&old_node_brother->leftChild->red_node == RED){old_node_brother->leftChild->red_node = old_node_parent->red_node;old_node_parent->red_node = BLACK;old_node_brother->leftChild->parent = old_node_parent;old_node_parent->rightChild = old_node_brother->leftChild;if (old_node_brother->leftChild->rightChild){old_node_brother->leftChild->rightChild->parent = old_node_brother;old_node_brother->leftChild = old_node_brother->leftChild->rightChild;}else{old_node_brother->leftChild = NULL;}old_node_brother->parent = old_node_parent->rightChild;old_node_parent->rightChild->rightChild = old_node_brother;old_node_brother = old_node_parent->rightChild;old_node_grend = old_node_parent->parent;if (old_node_brother->leftChild){old_node_brother->leftChild->parent = old_node_parent;old_node_parent->rightChild = old_node_brother->leftChild;}else{old_node_parent->rightChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->rightChild == old_node_parent){old_node_grend->rightChild = old_node_brother;}else{old_node_grend->leftChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->leftChild = old_node_parent;break;}}            }else{old_node_brother = old_node_parent->leftChild;if (old_node_brother->red_node == RED){old_node_brother->red_node = BLACK;old_node_parent->red_node = RED;if (old_node_brother->rightChild){old_node_brother->rightChild->parent = old_node_parent;old_node_parent->leftChild = old_node_brother->rightChild;}else{old_node_parent->leftChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->leftChild == old_node_parent){old_node_grend->leftChild = old_node_brother;}else{old_node_grend->rightChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->rightChild = old_node_parent;}else if (old_node_parent->leftChild->red_node == BLACK){bool red_p = old_node_parent->red_node == RED,b_bro_r = old_node_brother->leftChild&&old_node_brother->leftChild->red_node == BLACK,b_bro_l = old_node_brother->rightChild&&old_node_brother->rightChild->red_node == BLACK,null_node = !old_node_brother->rightChild&&!old_node_brother->leftChild;if (red_p && (null_node || (b_bro_l&&b_bro_r))){old_node_parent->red_node = BLACK;old_node_brother->red_node = RED;break;}else if (!red_p && (null_node || (b_bro_l&&b_bro_r))){old_node_brother->red_node = RED;break;}else if (old_node_brother->leftChild&&old_node_brother->leftChild->red_node == RED){old_node_brother->red_node = old_node_parent->red_node;old_node_parent->red_node = BLACK;old_node_brother->leftChild->red_node = BLACK;if (old_node_brother->rightChild){old_node_brother->rightChild->parent = old_node_parent;old_node_parent->leftChild = old_node_brother->rightChild;}else{old_node_parent->leftChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->leftChild == old_node_parent){old_node_grend->leftChild = old_node_brother;}else{old_node_grend->rightChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->rightChild = old_node_parent;break;}else if (old_node_brother->rightChild&&old_node_brother->rightChild->red_node == RED){ old_node_brother->rightChild->red_node = old_node_parent->red_node;old_node->parent->red_node = BLACK;old_node_brother->rightChild->parent = old_node_parent;old_node_parent->leftChild = old_node_brother->rightChild;if (old_node_brother->rightChild->leftChild){old_node_brother->rightChild->leftChild->parent = old_node_brother;old_node_brother->rightChild = old_node_brother->rightChild;}else{old_node_brother->rightChild = NULL;}old_node_brother->parent = old_node_parent->leftChild;old_node_parent->leftChild->leftChild = old_node_brother;old_node_parent = old_node->parent;old_node_grend = old_node_parent->parent;old_node_brother = old_node_parent->leftChild;if (old_node_brother->rightChild){old_node_brother->rightChild->parent = old_node_parent;old_node_parent->leftChild = old_node_brother->rightChild;}else{old_node_parent->leftChild = NULL;}if (old_node_grend){old_node_brother->parent = old_node_grend;if (old_node_grend->leftChild == old_node_parent){old_node_grend->leftChild = old_node_brother;}else{old_node_grend->rightChild = old_node_brother;}}else{root = old_node_brother;old_node_brother->parent = NULL;}old_node_parent->parent = old_node_brother;old_node_brother->rightChild = old_node_parent;break;}}}}}delete old_node;}


0 0
原创粉丝点击