红黑树是一颗特殊的二叉排序树(BST)即一定满足左子树结点值<=根结点值<=右子树结点值,但同时还需要满足:
- 每个结点要么是红色,要么是黑色
- 根节点以及叶结点一定是黑色(此处叶结点为查找失败结点)
- 红色结点的父结点以及儿子结点一定是黑色(不存在相邻的两个红色结点)
- 对于每个结点来说从该结点到任意叶结点的简单路径上,所含黑色结点的数目相同(具体的数目个数称为黑高)
struct RBnode{//红黑树结构体
int key;//关键字值
RBnode* parent; //父结点指针
RBnode* lchild; //左孩子
RBnode* rchild; //右孩子
int color; //结点颜色,0黑1红
}
红黑树进行插入操作时需要先确定插入位置,保证满足左子树结点值<=根结点值<=右子树结点值,此处同平衡二叉树和二叉排序树,插入新结点后要进行如下平衡调整:
- 如果新结点为根,则染为黑色,否则染为红色(保证到任意叶结点的简单路径上,所含黑色结点的数目相同)
- 插入后判断是否满足红黑树的定义,满足则插入结束
- 如果不满足红黑树定义(一般是不满足红色结点的父结点和子结点均为黑色)则需要对红黑树进行调整,通过插入结点父结点的兄弟颜色(以下称为叔结点)来进行调整
- 如果叔结点为黑色需进行如下操作(旋转+染色,不同类型的旋转操作同平衡二叉树调整最小不平衡子树即可):
- LL型:右单旋,父换爷同时父、爷颜色取反
- RR型:左单旋,父换爷同时父、爷颜色取反
- LR型:左、右双旋,儿换爷同时儿、爷颜色取反
- RL型:右、左双旋,儿换爷同时儿、爷颜色取反
- 如果叔结点为红色则仅需叔结点、父结点、爷结点颜色取反,爷结点看作为新结点继续调整即可