red_black_tree
red black tree impl
一些要点:
红黑树可以转换成2-3树, 只要将红色节点往其父节点提到相同的高度, 并将这两个节点融合到一起即可
红黑树是难得的 插入、搜索、删除的时间复杂度都能维持在logN的平衡二叉树, 但其不是绝对平衡的
红黑树的特性: a-> 每个节点只有两种红的或黑的 b-> 根节点绝对是黑色的 c-> 不能出现两个相邻的红色节点, 依据这个特点, 我们可以推断处一些东西 d-> 从任意节点到其所有叶子节点的简单路径上经过的黑色节点的数目是相同的
红黑树在插入、删除一个节点后, 需要根据插入、删除后是否还能维持红黑树的特性决定是否进行 调整以在插入、删除过后还是一颗红黑树, 这主要通过红黑树主要通过旋转以及着色操作来调整
插入节点
为了实现上面的便利, 约定待插入的节点以红节点的形式被插入到红黑树中
case 1. 插入一颗空树, 此时需要对新插入的节点进行recolour()
case 2. 在黑色节点下插入一个红子节点 , 此时不需要对树进行调整操作
case 3. 待插入的节点是红色的and其父节点也是红色的 && 且它们都是右斜的 && 没有红色uncle节点(黑色uncle或者无uncle)
此时, 需要对以该节点的父节点作为支点进行一个左旋操作 rotate-left(), 然后, 将旋转
过后的父节点的颜色与其左节点的颜色互换,
那么, 其旋转操作也是一样的, 只是红黑树又加了一些约束, 需要在旋转过后再执行一个重新染色以符合性质的操作
节点的删除
红黑树与2-3-4树的等价
红黑树是一颗二叉树, 那么其就拥有一种拥有两个子节点的节点, 称为二结点
2-3-4树是4阶b树, 有三种类型的节点
- 二结点
- 三节点
- 四节点
2-3-4树实现上比较繁琐, 通常用红黑树的实现方式实现2-3-4树
ps: 在向一个红黑树a插入一个节点时, 我们在插入之前可以确定的是, 此时的红黑树a是一颗正确的红黑树, 符合红黑树的特点, 那么其树内是绝 不会出现两了连续的红色节点的, 视角回到我们找到合适的插入位置的那一刻, 如果此时我们找到的合适的插入位置(即parent节点)是红色的,那么 parent的parent就一定是黑色的, 这是我们在插入时, 根据红黑树的特性所推断出来的, 而这个信息是相当有用的
红黑树的实现
节点定义
c
struct red_black_node {
void *item;
struct red_black_node *left;
struct red_black_node *right;
struct red_black_node *parent;
enum { RED, BLACK } color_t;
};