以下是一个简单的红黑树实现示例:

#include <stdio.h>
#include <stdlib.h>

enum Color {RED, BLACK};

typedef struct Node {
    int key;
    enum Color color;
    struct Node *left, *right, *parent;
} Node;

Node *root = NULL;

Node *createNode(int key) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->key = key;
    newNode->color = RED;
    newNode->left = newNode->right = newNode->parent = NULL;
    return newNode;
}

void leftRotate(Node *x) {
    Node *y = x->right;
    x->right = y->left;
    if (y->left != NULL) {
        y->left->parent = x;
    }
    y->parent = x->parent;
    if (x->parent == NULL) {
        root = y;
    } else if (x == x->parent->left) {
        x->parent->left = y;
    } else {
        x->parent->right = y;
    }
    y->left = x;
    x->parent = y;
}

void rightRotate(Node *x) {
    Node *y = x->left;
    x->left = y->right;
    if (y->right != NULL) {
        y->right->parent = x;
    }
    y->parent = x->parent;
    if (x->parent == NULL) {
        root = y;
    } else if (x == x->parent->right) {
        x->parent->right = y;
    } else {
        x->parent->left = y;
    }
    y->right = x;
    x->parent = y;
}

void fixViolation(Node *newNode) {
    Node *parent, *grandparent;
    while (newNode != root && newNode->color != BLACK && newNode->parent->color == RED) {
        parent = newNode->parent;
        grandparent = newNode->parent->parent;
        if (parent == grandparent->left) {
            Node *uncle = grandparent->right;
            if (uncle != NULL && uncle->color == RED) {
                grandparent->color = RED;
                parent->color = BLACK;
                uncle->color = BLACK;
                newNode = grandparent;
            } else {
                if (newNode == parent->right) {
                    leftRotate(parent);
                    newNode = parent;
                    parent = newNode->parent;
                }
                rightRotate(grandparent);
                int temp = parent->color;
                parent->color = grandparent->color;
                grandparent->color = temp;
                newNode = parent;
            }
        } else {
            Node *uncle = grandparent->left;
            if (uncle != NULL && uncle->color == RED) {
                grandparent->color = RED;
                parent->color = BLACK;
                uncle->color = BLACK;
                newNode = grandparent;
            } else {
                if (newNode == parent->left) {
                    rightRotate(parent);
                    newNode = parent;
                    parent = newNode->parent;
                }
                leftRotate(grandparent);
                int temp = parent->color;
                parent->color = grandparent->color;
                grandparent->color = temp;
                newNode = parent;
            }
        }
    }
    root->color = BLACK;
}

void insert(int key) {
    Node *newNode = createNode(key);
    Node *current = root;
    Node *parent = NULL;
    while (current != NULL) {
        parent = current;
        if (newNode->key < current->key) {
            current = current->left;
        } else {
            current = current->right;
        }
    }
    newNode->parent = parent;
    if (parent == NULL) {
        root = newNode;
    } else if (newNode->key < parent->key) {
        parent->left = newNode;
    } else {
        parent->right = newNode;
    }
    fixViolation(newNode);
}

void inorderTraversal(Node *node) {
    if (node != NULL) {
        inorderTraversal(node->left);
        printf("%d ", node->key);
        inorderTraversal(node->right);
    }
}

int main() {
    insert(7);
    insert(3);
    insert(18);
    insert(10);
    insert(22);
    insert(8);
    insert(11);
    insert(26);
    inorderTraversal(root);
    return 0;
}

红黑树的插入操作包括两个部分:插入节点和修复违规(violation)。插入节点与二叉搜索树类似,但需要将节点的颜色设置为红色。修复违规分为两种情况,一种是父节点和叔节点都是红色,需要将父节点和叔节点都变为黑色,祖父节点变为红色,然后继续向上修复;另一种是父节点为红色,叔节点为黑色(或者为NULL),需要通过旋转将父节点和祖父节点的颜色交换,然后向上修复。最后需要将根节点的颜色设置为黑色。

以上红黑树实现中还包括左旋和右旋操作,用于修复第二种违规情况。左旋操作将x节点向左旋转,使得其右子节点y成为x的父节点,x成为y的左子节点;右旋操作将x节点向右旋转,使得其左子节点y成为x的父节点,x成为y的右子节点。

此外,红黑树的删除操作也需要进行修复违规操作,但比插入操作更为复杂,这里不再详细讨论

用C实现一个红黑树

原文地址: http://www.cveoy.top/t/topic/ehpD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录