情况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 0
template<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;
else
cout << "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;//parent
old_node_grend = old_node_parent->parent;//grandfather
if (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;
}