红黑树实现(C语言)

红黑树是一种自平衡的二叉查找树,它通过对节点的颜色进行约束,确保了树的高度始终保持在log(n)级别,其中n是树中节点的数量。红黑树的特点是:

  1. 每个节点或者是红色,或者是黑色。
  2. 根节点是黑色。
  3. 每个叶子节点(NIL节点,空节点)是黑色。
  4. 如果一个节点是红色的,则它的子节点必须是黑色的。
  5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
    以下是红黑树主要功能的实现原理和C语言代码实现,每行代码都有详细注释:
  6. 创建节点:为新节点分配内存,并初始化其属性。
// 定义红黑树节点的颜色
#define RED 0
#define BLACK 1
// 定义红黑树节点结构体
typedef struct Node {
    int data; // 节点存储的数据
    int color; // 节点的颜色
    struct Node *left; // 左子节点
    struct Node *right; // 右子节点
    struct Node *parent; // 父节点
} Node;
// 创建一个新的红黑树节点
Node* createNode(int data) {
    Node* node = (Node*)malloc(sizeof(Node)); // 为新节点分配内存
    node->data = data; // 初始化节点数据
    node->color = RED; // 新创建的节点默认为红色
    node->left = NULL; // 初始化左子节点为NULL
    node->right = NULL; // 初始化右子节点为NULL
    node->parent = NULL; // 初始化父节点为NULL
    return node; // 返回新创建的节点
}
  1. 插入节点:将新节点插入到红黑树中,并维护红黑树的性质。
// 插入节点到红黑树
void insertNode(Node** root, Node* node) {
    // 如果树为空,直接将新节点作为根节点
    if (*root == NULL) {
        *root = node;
        node->color = BLACK; // 根节点必须是黑色
        return;
    }
    // 找到新节点的插入位置
    Node* current = *root;
    Node* parent = NULL;
    while (current != NULL) {
        parent = current;
        if (node->data < current->data) {
            current = current->left;
        } else {
            current = current->right;
        }
    }
    // 将新节点插入到红黑树中
    node->parent = parent;
    if (node->data < parent->data) {
        parent->left = node;
    } else {
        parent->right = node;
    }
    // 维护红黑树的性质
    fixInsert(node);
}
  1. 维护红黑树的性质:在插入节点后,通过一系列的旋转和颜色变换来维护红黑树的性质。
// 维护红黑树的性质
void fixInsert(Node* node) {
    // 如果新节点是根节点,直接将其颜色设置为黑色
    if (node->parent == NULL) {
        node->color = BLACK;
        return;
    }
    // 如果父节点是黑色,不需要调整
    if (node->parent->color == BLACK) {
        return;
    }
    // 获取祖父节点
    Node* grandparent = node->parent->parent;
    // 获取叔叔节点
    Node* uncle = NULL;
    if (grandparent != NULL) {
        if (node->parent == grandparent->left) {
            uncle = grandparent->right;
        } else {
            uncle = grandparent->left;
        }
    }
    // 如果叔叔节点是红色,需要调整
    if (uncle != NULL && uncle->color == RED) {
        node->parent->color = BLACK;
        uncle->color = BLACK;
        grandparent->color = RED;
        fixInsert(grandparent);
    } else {
        // 如果叔叔节点是黑色,需要进行旋转操作
        if (node == node->parent->right && node->parent == grandparent->left) {
            rotateLeft(node->parent);
            node = node->left;
        } else if (node == node->parent->left && node->parent == grandparent->right) {
            rotateRight(node->parent);
            node = node->right;
        }
        node->parent->color = BLACK;
        grandparent->color = RED;
        if (node == node->parent->left) {
            rotateRight(grandparent);
        } else {
            rotateLeft(grandparent);
        }
    }
}
  1. 旋转操作:左旋转和右旋转是红黑树调整树结构以保持平衡的关键操作。
// 左旋转
void rotateLeft(Node* node) {
    Node* rightChild = node->right;
    node->right = rightChild->left;
    if (node->right != NULL) {
        node->right->parent = node;
    }
    rightChild->parent = node->parent;
    if (node->parent == NULL) {
        root = rightChild;
    } else if (node == node->parent->left) {
        node->parent->left = rightChild;
    } else {
        node->parent->right = rightChild;
    }
    rightChild->left = node;
    node->parent = rightChild;
}
// 右旋转
void rotateRight(Node* node) {
    Node* leftChild = node->left;
    node->left = leftChild->right;
    if (node->left != NULL) {
        node->left->parent = node;
    }
    leftChild->parent = node->parent;
    if (node->parent == NULL) {
        root = leftChild;
    } else if (node == node->parent->left) {
        node->parent->left = leftChild;
    } else {
        node->parent->right = leftChild;
    }
    leftChild->right = node;
    node->parent = leftChild;
}
  1. 打印红黑树:以图形化的方式打印红黑树,以便于观察树的结构。
// 打印红黑树
void printTree(Node* node, int space) {
    int i;
    if (node == NULL) {
        return;
    }
    space += 10;
    printTree(node->right, space);
    printf("\n");
    for (i = 10; i < space; i++) {
        printf(" ");
    }
    printf("%d(%d)\n", node->data, node->color);
    printTree(node->left, space);
}

以上代码实现了一个简单的红黑树,包括创建节点、插入节点、维护红黑树的性质、旋转操作和打印树的功能。在插入节点时,会调用fixInsert函数来维护红黑树的性质。代码中还包括了左旋转和右旋转的函数,这是红黑树调整树结构以保持平衡的关键操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请向我看齐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值