我们都听过平衡二叉树(AVLTree),了解到AVL树的性质,其实平衡二叉树最大的作用就是查找,AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。AVL树的效率就是高在这个地方。如果在AVL树中插入或删除节点后,使得高度之差大于1。此时,AVL树的平衡状态就被破坏,它就不再是一棵二叉树;为了让它重新维持在一个平衡状态,就需要对其进行旋转处理, 那么创建一颗平衡二叉树的成本其实不小. 这个时候就有人开始思考,并且提出了红黑树的理论,那么红黑树到底比AVL树好在哪里?
红黑树与AVL树的比较:
红黑树是一棵二叉搜索树,它在每个节点增加了一个存储位记录节点的颜色,可以是RED,也可以是BLACK;通过任意一条从根到叶子简单路径上颜色的约束,红黑树保证最长路径不超过最短路径的二倍,因而近似平衡。
具体性质如下:
你的最短路径就是全黑节点,最长路径就是一个红节点一个黑节点,最后黑色节点相同时,最长路径刚好是最短路径的两倍
红黑树插入节点过程大致分析:
RBTree为二叉搜索树,我们按照二叉搜索树的方法对其进行节点插入
RBTree有颜色约束性质,因此我们在插入新节点之后要进行颜色调整
具体步骤如下:
首先红黑树的插入其实不是那么容易实现的,以前搜索树的插入我们很容易理解现在我们首先思考一个问题,你插入节点的默认颜色是RED或BLACK? 这里我们需要根据性质来思考,首先如果插入黑节点,这个可以直接插入无论它的父亲是什么颜色,但是红黑树的性质是每条路径的黑色节点数目相同这个时候你再想想那其他路径的黑色节点数目一定比你现在少一个节点,所以调整起来是非常繁琐的. 插入红节点不需要调整其他路径,如果它的父亲为黑,那么直接插入,如果他的父亲为红那么在该路径上面开始分情况调整. 所以插入节点默认颜色一定要为红.如果为黑调节成本太大了.接下来开始插入节点如果插入节点的父亲为黑那么直接插入后返回不需要做任何调整. 但是如果插入节点的父亲为红,那么就需要调整了.具体的调整过程可以分为三个情况:
第一种情况
cur为红,parent为红,pParent为黑,uncle存在且为红
则将parent,uncle改为黑,pParent改为红,然后把pParent当成cur,继续向上调整。
此时对该子树进行操作,parent节点和uncle节点变为黑,pParent节点变为红,这样我们就保证该子树中每条路径中黑色节点相同并且没有连续的红节点,然后再让cur等于pParent节点继续往上继续调整。
第二种情况
cur为红,parent为红,pParent为黑,uncle不存在/u为黑
parent为pParent的左孩子,cur为parent的左孩子,则进行右单旋转;
第三种情况
cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转
则转换成了情况2
boolean Insert( const K& key, const V& value)
{
//根节点为空
if (_root == NULL)
{
_root = new Node(key,value);
_root->_color = BLACK;
return true ;
}
//根节点不为空
//找到新节点插入位置
Node* parent = NULL;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key >key)
{
parent = cur;
cur = cur->_left;
}
else
return false ;
}
//插入新节点
cur = new Node(key, value);
cur->_color = RED;
if (parent->_key > key)
{
parent->_left = cur;
cur->_parent = parent;
}
else //parent->_key < key
{
parent->_right = cur;
cur->_parent = parent;
}
//插入节点后颜色的调整
while (parent && parent->_color == RED)
{
Node* grandfather = parent->_parent; //grandfather颜色一定为黑色
if (parent == grandfather->_left)
{
Node* uncle = grandfather->_right;
//uncle存在且为红
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
cur = grandfather;
parent = cur->_parent;
}
else //uncle不存在/uncle存在且为黑
{
if (cur == parent->_right)
{
RotateL(parent);
swap(parent, cur);
}
RotateR(grandfather);
parent->_color = BLACK;
grandfather->_color = RED;
}
}
else //grandfather->_right==parent
{
Node* uncle = grandfather->_left;
//uncle存在且为红
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
grandfather->_color = RED;
cur = grandfather;
parent = cur->_parent;
}
else //不存在/存在且为黑
{
if (cur == parent->_left)
{
RotateR(parent);
swap(cur, parent);
}
RotateL(grandfather);
parent->_color = BLACK;
grandfather->_color = RED;
}
}
} //end while (parent && parent->_color == RED)
_root->_color = BLACK;
return true ;
}
代码小兵64503-29 11:46
代码小兵87208-06 11:36
代码小兵34507-29 13:19