红黑树基础操作
性质
- 每个节点要么是黑色,要么是红色
- 根节点是黑色
- 每个叶子结点(NIL)是黑色
- 每个红色节点的两个子节点一定都是黑色,即不能有两个红色节点相连
- 任意一节点到每个叶子结点的路径都包含数量相同的黑节点(俗称“黑高”)
- 推论:如果一个节点存在黑子节点,那么该节点肯定有两个子节点。
自平衡操作
变色:结点的颜色由红变黑或由黑变红。
左旋:以某个节点作为支点(旋转节点),其右子节点变为旋转节点的父节点,右子节点的左子节点变为旋转节点的右子节点,左子节点保持不变。
- 右旋:以某个节点作为支点(旋转节点),其左子节点变为旋转节点的父节点,左子节点的右子节点变为旋转节点的左子节点,右节点保持不变。
插入操作
插入节点时,节点必须为红色。
原因:红色在父节点为黑色节点时,红黑树的黑色平衡没有被破坏,不需要做自平衡操作。但如果插入节点为黑色,那么插入位置所在的子树黑色节点总是多1,必须做自平衡。
术语
插入情景
- 红黑树为空树:直接把插入节点作为根节点,并把插入节点设置为黑色。
- 插入节点的Key已经存在:更新当前节点的值为插入节点的值。
- 插入节点的父节点为黑色:由于插入的节点是红色的,当父节点是黑色时,并不会影响红黑树的平衡,直接插入即可,无需做自平衡。
插入节点的父节点为红色:如果插入节点的父节点为红节点,那么该父节点不可能为根节点,所以插入节点总是存在祖父节点。
- 叔叔节点存在并且为红节点
- 将P和U节点改为黑色
- 将PP改为红色
- 将PP设置为当前节点,进行后续处理(即如果PP的父节点也是红色,则继续以PP为当前节点进行插入操作自平衡处理,直到平衡为止)
叔叔节点不存在或为黑节点,并且插入节点的父亲节点是祖父节点的左子节点
新插入的节点是其父节点的左子节点(LL双红)
- 变色:将P设置为黑色,将PP设置为红色
- 对PP节点进行右旋
新插入的节点是其父节点的右子节点(LR双红)
- 对P进行左旋
- 将P设置为当前节点,得到“LL双红”的情况
- 按照“LL双红”的情况处理(变颜色、右旋PP)
叔叔节点不存在或为黑节点,并且插入节点的父亲节点是祖父节点的右子节点
新插入的节点是其父节点的右子节点(RR双红)
- 变色:将P设置为黑色,将PP设置为红色
- 对PP节点进行左旋
新插入的节点是其父节点的左子节点(RL双红)
- 对P进行右旋
- 将P设置为当前节点,得到“RR红色”的情况
- 按照“RR红色”情况处理(变颜色、左旋PP)
- 叔叔节点存在并且为红节点