📅  最后修改于: 2023-12-03 15:27:32.447000             🧑  作者: Mango
红黑树是一种自平衡二叉搜索树。
自平衡二叉搜索树是一种二叉搜索树,其中每个节点都附加了平衡条件。这样可以保证搜索树的高度在一定范围内,从而使树的操作(例如查找、插入和删除)的时间复杂度保持在 O(log n)。
而红黑树是一种自平衡二叉搜索树,通过对插入和删除操作的平衡化运算来保持树的高度在一定范围内,从而保证了搜索树的操作性能。
红黑树有以下规则:
节点是红色或黑色。
根是黑色的。
所有叶子都是黑色的(叶子是 NIL 节点)。
每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点)。
从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
红黑树的插入操作通常采用递归的方式实现,其代码如下所示:
// 向红黑树中插入一个节点
void insert(struct node **root, int key) {
// 新建一个节点
struct node *z = malloc(sizeof(struct node));
z->key = key;
z->left = z->right = NULL;
z->color = RED;
// 调用插入递归函数
*root = insertNode(*root, z);
(*root)->color = BLACK; // 根节点必须为黑色
}
// 插入递归函数
struct node* insertNode(struct node *root, struct node *z) {
// 如果插入的节点为空,则返回新建的节点
if (root == NULL) {
return z;
}
// 如果插入节点的值比当前节点的值小,则插入到当前节点的左侧
if (z->key < root->key) {
root->left = insertNode(root->left, z);
}
// 否则插入到当前节点的右侧
else {
root->right = insertNode(root->right, z);
}
// 根据红黑树规则调整节点的颜色
if (isRed(root->right) && !isRed(root->left)) {
root = rotateLeft(root);
}
if (isRed(root->left) && isRed(root->left->left)) {
root = rotateRight(root);
}
if (isRed(root->left) && isRed(root->right)) {
flipColors(root);
}
// 返回调整后的节点
return root;
}
代码中,节点颜色用 enum
类型的变量表示,插入时先插入红色节点,再根据红黑树规则调整节点的颜色。这里使用了三种颜色调整的操作:
左旋转:将红色节点向左旋转一次,使其成为一个子节点。
右旋转:将红色节点向右旋转一次,使其成为一个子节点。
颜色反转:将父节点和两个子节点的颜色调换,使红色节点向根的路径上下传。
红黑树插入操作的实现比较复杂,需要根据红黑树规则对节点的颜色进行调整。但是,这种自平衡的二叉搜索树可以使二叉搜索树保持平衡,从而保证二叉搜索树的操作性能。