红黑树及相关操作

红黑树是C++标准模板库中set的基础,遵循特定的着色规则。插入新节点时,如果导致连续两个红色节点,需要通过颜色改变和旋转来保持平衡。自底向上插入时可能需要上滤调整,自顶向下插入则通过颜色反转和旋转避免连续红节点。本文探讨了这两种方法及C/C++实现。
摘要由CSDN通过智能技术生成

红黑树

红黑树是一种常用的平衡二叉树,C++标准模板库中的set正是基于红黑树构造。红黑树具有以下几个性质:

  • (1) 每个节点被着色成红色或黑色。
  • (2) 树的根节点是黑色的。
  • (3) 如果一个节点是红色的,则它的子节点必须是黑色的(即两个红色的节点不能连续出现)。
  • (4) 从一个节点到一个NULL指针的没一条路径必须包含相同数目的黑色节点。

一个红黑树的例子
这里写图片描述


自底向上红黑树

由于条件(4)的存在,使得如果新插入的项为叶节点,则该节点的颜色必须为红色。如果插入之后其父节点为黑色,则插入完成。比如上图红黑树中插入7。

而如果新节点的父节点为红色(比如上图插入36),则出现了连续的两个红色节点,不满足条件(3)。则此时需要对树进行调整(颜色改变和旋转)。

  • 一字形旋转(单旋转)

如下图假如要插入的新的叶节点为X,P为其父节点,S为P的兄弟节点,G为X的祖父节点。X和P都是红色,则需要对树结构进行调整。先基于P和G做一次单左旋,然后对新根着黑色,新根的两个孩子都着红色。
这里写图片描述

  • 之字形旋转(双旋转)

下图对应需要进行双(左)旋转的情况,而双旋转可以分成两次单旋转,即现在P和X进行一次单右旋然后再G和X之间进行一次单左旋。
这里写图片描述

然而,当将79插入至本例的二叉树中时,由于其父节点80及其兄弟节点85都是红色的,以至于旋转过后依然会出现两个红色连续的情况。即:
这里写图片描述
这种情况出现时,需要从底部向上进行“上滤”的不断调整树使得树满足红黑树的条件。


自顶向下红黑树

自底向上时,上滤的操作需要用到栈或父级指针保存路径。自顶向下类似于伸展树的过程保证不出现连续两个红节点。
在向下的过程中,如果一个节点X有两个红孩子,则可以让X变成红的,两个孩子变成黑的。这种简单颜色反转也可能会造成连续的红节点出现(当X的父节点P也是红色的时候)这时需要对树进行旋转操作。而X父节点P的兄弟节点不可能为红色(自顶向下的保证)

例如,要将45插入到下图的红黑树中:
这里写图片描述
在自顶向下的过程中,发现50的两个孩子40和55都为红色,则反转颜色50为红色,45和55都为黑色。这时出现了50和60两个连续红色则需要在70和60之间进行一次单左旋。使得60变成30的右孩子着色为黑,50和70分别成为60的左右孩子都着色为红。最后在黑节点40直接插入新的红节点45,使得整个树满足红黑树的条件。


红黑树实现及相关操作C/C++

#include<iostream>
using namespace std;

#define ElementType int
enum ColorType {Red, Black};    // 定义颜色为枚举类型


typedef struct TreeNode {
    ElementType value;      // 节点关键字值
    TreeNode* left;     // 左孩子
    TreeNode* right;    // 右孩子
    ColorType color;        // 节点颜色
}RedBlackNode, *Re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值