正如这篇博文中说到的金山网络面试经历 http://blog.youkuaiyun.com/huruzun/article/details/24634593 面试官要自己设计数据结构实现容器类,需要尽快的实现插入删除查找,在现实实现STL 容器类中红黑树被广泛的应用。
平衡二叉树(BalancedBinary Tree或Height-Balanced Tree)又称AVL树。它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。若将二叉树上结点的平衡因子BF(BalanceFactor)定义为该结点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有结点的平衡因子只可能是-1、0和1。(此段定义来自严蔚敏的《数据结构(C语言版)》)
红黑树严格意义上不满足平衡因子绝对值小于等于1情况,下面代码就进行测试。
我们知道一颗高度为h的二叉查找树可以实现任何一种基本的动态集合操作,其时间复杂度为 O(h)。这样在树高度比较低时,基本动态操作如插入、删除 会执行的很快,但是当树的高度较高是,尤其是极端情况下的树结构 退化成链表插入删除效率。如上面所说红黑树是许多“平衡的”的查找树中一种,它能保证在最坏情况下,基本动态集合操作的时间为 O(lgn)n 为树结点数目。
本文代码实现参考下面两篇博文感谢作者:http://blog.youkuaiyun.com/npy_lp/article/details/7420689
http://blog.youkuaiyun.com/v_JULY_v/article/details/6114226 JULY 博客强力推荐,他对算法理解很好。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
typedef int key_t;
typedef int data_t;
typedef enum color_t
{
RED = 0,
BLACK = 1
}color_t;
typedef struct rb_node_t
{
struct rb_node_t *left, *right, *parent;
key_t key;
data_t data;
color_t color;
}rb_node_t;
/* forward declaration */
rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root);
rb_node_t* rb_search(key_t key, rb_node_t* root);
rb_node_t* rb_erase(key_t key, rb_node_t* root);
static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root)
{
rb_node_t* right = node->right;
if ((node->right = right->left))//注意括号里面只是一个等号
{
right->left->parent = node;
}
right->left = node;
if ((right->parent = node->parent))
{
if (node == node->parent->right)
{
node->parent->right = right;
}
else
{
node->parent->left = right;
}
}
else
{
root = right;
}
node->parent = right;
return root;
}
static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root)
{
rb_node_t* left = node->left;
if ((node->left = left->right))
{
left->right->parent = node;
}
left->right = node;
if ((left->parent = node->parent))
{
if (node == node->parent->right)
{
node->parent->right = left;
}
else
{
node->parent->left = left;
}
}
else
{
root = left;
}
node->parent = left;
return root;
}
static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root)
{
rb_node_t *parent, *gparent, *uncle, *tmp;
//循环大的控制条件是 node 的 parent 颜色是红色才进入循环处理
while ((parent = node->parent) && parent->color == RED)
{
gparent = parent->parent;
if (parent == gparent->left)
{
uncle = gparent->right;//情况 1 node的叔叔是红色的情况
if (uncle && uncle->color == RED)
{
uncle->color = BLACK;
parent->color = BLACK;
gparent->color = RED;
node = gparent;
}//情况 2 ,3 node 的叔叔是黑色的
else
{
//情况 2 node 是parent的右孩子
if (parent->right == node)
{
root = rb_rotate_left(parent, root);
// 左旋过后 交换 parent与node 位置
tmp = parent;
parent = node;
node = tmp;
}
//情况 3 node 是parent的左孩子
parent->color = BLACK;
gparent->color = RED;
root = rb_rotate_right(gparent, root);
}
}
// 算法导论中写道 :same as then with "right" and "left" exchanged 下面代码实现类似,只是把left换成 right
else
{
uncle = gparent->left;
if (uncle && uncle->color == RED)
{
uncle->color = BLACK;
parent->color = BLACK;
gparent->color = RED;
node = gparent;
}
else
{
if (parent->left == node)
{
root = rb_rotate_right(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->color = BLACK;
gparent->color = RED;
root = rb_rotate_left(gparent, root);
}
}
}
root->color = BLACK;
return root;
}
static rb_node_t* rb_new_node(key_t key, data_t data)
{
rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t));
if (!node)
{
printf("malloc error!\n");
exit(-1);
}
node->key = key, node->data = data;
return node;
}
static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save)
{
rb_node_t *node = root, *parent = NULL;
int ret;
while (node)
{
parent = node;
ret = node->key - key;
if (0 < ret)
{
node = node->left;
}
else if (0 > ret)
{
node = node->right;
}
else
{
return node;
}
}
if (save)
{
*save = parent;
}
return NULL;
}
rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root)
{
rb_node_t *parent = NULL, *node;
parent = NULL;
if ((node = rb_search_auxiliary(key, root, &parent)))//函数返回node需要插入的位置,并且更新parent为node的parent
{
return root;//node 已经存在情况直接返回
}
node = rb_new_node(key, data);//产生新结点函数,更好实现模块化
//新插入节点left right 指向NULL ,颜色给成红色
node->parent = parent;
node->left = node->right = NULL;
node->color = RED;
// 使得parent 指向 node结点
if (parent)
{
if (parent->key > key)
{
parent->left = node;
}
else
{
parent->right = node;
}
}
else
{
root = node;
}
return rb_insert_rebalance(node, root);
}
rb_node_t* rb_search(key_t key, rb_node_t* root)
{
return rb_search_auxiliary(key, root, NULL);
}
static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root)
{
rb_node_t *other, *o_left, *o_right;
while ((!node || node->color == BLACK) && node != root)
{
if (parent->left == node)
{
other = parent->right;
if (other->color == RED)
{
other->color = BLACK;
parent->color = RED;
root = rb_rotate_left(parent, root);
other = parent->right;
}
if ((!other->left || other->left->color == BLACK) &&
(!other->right || other->right->color == BLACK))
{
other->color = RED;
node = parent;
parent = node->parent;
}
else
{
if (!other->right || other->right->color == BLACK)
{
if ((o_left = other->left))
{
o_left->color = BLACK;
}
other->color = RED;
root = rb_rotate_right(other, root);
other = parent->right;
}
other->color = parent->color;
parent->color = BLACK;
if (other->right)
{
other->right->color = BLACK;
}
root = rb_rotate_left(parent, root);
node = root;
break;
}
}
else
{
other = parent->left;
if (other->color == RED)
{
other->color = BLACK;
parent->color = RED;
root = rb_rotate_right(parent, root);
other = parent->left;
}
if ((!other->left || other->left->color == BLACK) &&
(!other->right || other->right->color == BLACK))
{
other->color = RED;
node = parent;
parent = node->parent;
}
else
{
if (!other->left || other->left->color == BLACK)
{
if ((o_right = other->right))
{
o_right->color = BLACK;
}
other->color = RED;
root = rb_rotate_left(other, root);
other = parent->left;
}
other->color = parent->color;
parent->color = BLACK;
if (other->left)
{
other->left->color = BLACK;
}
root = rb_rotate_right(parent, root);
node = root;
break;
}
}
}
if (node)
{
node->color = BLACK;
}
return root;
}
rb_node_t* rb_erase(key_t key, rb_node_t *root)
{
rb_node_t *child, *parent, *old, *left, *node;
color_t color;
//先查找删除结点值是否存在
if (!(node = rb_search_auxiliary(key, root, NULL)))
{
printf("key %d is not exist!\n");
return root;
}
old = node;
if (node->left && node->right)
{
node = node->right;
while ((left = node->left) != NULL)
{
node = left;
}
child = node->right;
parent = node->parent;
color = node->color;
if (child)
{
child->parent = parent;
}
if (parent)
{
if (parent->left == node)
{
parent->left = child;
}
else
{
parent->right = child;
}
}
else
{
root = child;
}
if (node->parent == old)
{
parent = node;
}
node->parent = old->parent;
node->color = old->color;
node->right = old->right;
node->left = old->left;
if (old->parent)
{
if (old->parent->left == old)
{
old->parent->left = node;
}
else
{
old->parent->right = node;
}
}
else
{
root = node;
}
old->left->parent = node;
if (old->right)
{
old->right->parent = node;
}
}
else
{
if (!node->left)
{
child = node->right;
}
else if (!node->right)
{
child = node->left;
}
parent = node->parent;
color = node->color;
if (child)
{
child->parent = parent;
}
if (parent)
{
if (parent->left == node)
{
parent->left = child;
}
else
{
parent->right = child;
}
}
else
{
root = child;
}
}
free(old);
if (color == BLACK)
{
root = rb_erase_rebalance(child, parent, root);
}
return root;
}
void inorder(rb_node_t *root)
{
if (root!=NULL)
{
inorder(root->left);
cout<<"key="<<root->key<<" color="<<root->color<<endl;
inorder(root->right);
}
}
int main()
{
int test[6]={41,38,31,12,19,8};
rb_node_t* root = NULL, *node = NULL;
int i;
for (i=0;i<6;i++)
{
if ((root = rb_insert(test[i], i, root)))
{
printf("[i = %d] insert key %d success!\n", i+1, test[i]);
}
else
{
printf("[i = %d] insert key %d error!\n", i+1, test[i]);
exit(-1);
}
}
inorder(root);
return 0;
}
main 函数测试了算法导论给的思考题。
如果读者不理解算法过程可以参考算法导论或者JULY博文:http://blog.youkuaiyun.com/v_JULY_v/article/details/6109153