I'm trying to implement red-black trees in C. I was studying from the source code on GeeksForGeek and tried implementing it in C (since, originally it was in C++). When I ran the code I wrote, it is generating a tree whose root is always either 2, 4, 8, 16 32 ... (depending on the input, since my input is integer starting from 1 in ascending order). Can someone please point out something that I've been doing wrong?
#include <stdio.h>
#include <stdlib.h>
enum Color {
BLACK, RED
};
struct node {
int key;
struct node *left, *right, *parent;
enum Color color;
};
struct node* NewNode(int key) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
if (NULL == temp) {
return NULL;
}
temp->key = key;
temp->left = temp->right = temp->parent = NULL;
temp->color = RED;
return temp;
}
struct node* BSTInsert(struct node **root, struct node **insert) {
if (NULL == *root) {
return *insert;
}
else {
if ((*insert)->key < (*root)->key) {
(*root)->left = BSTInsert(&((*root)->left), insert);
(*root)->left->parent = *root;
}
else if ((*insert)->key > (*root)->key) {
(*root)->right = BSTInsert(&((*root)->right), insert);
(*root)->right->parent = *root;
}
return *root;
}
}
void RotateLeft(struct node **root, struct node **insert) {
struct node *right_node = (*insert)->right;
(*insert)->right = right_node->left;
if (NULL != (*insert)->right) {
(*insert)->right->parent = (*insert);
}
right_node->parent = (*insert)->parent;
if (NULL == (*insert)->parent) {
*root = right_node;
}
else if ((*insert) == (*insert)->parent->left){
(*insert)->parent->left = right_node;
}
else {
(*insert)->parent->right = right_node;
}
right_node->left = *insert;
(*insert)->parent = right_node;
}
void RotateRight(struct node **root, struct node **insert) {
struct node *left_node = (*insert)->left;
(*insert)->left = left_node->right;
if (NULL != (*insert)->left) {
(*insert)->left->parent = (*insert);
}
left_node->parent = (*insert)->parent;
if (NULL == (*insert)->parent) {
*root = left_node;
}
else if ((*insert) == (*insert)->parent->left) {
(*insert)->parent->left = left_node;
}
else {
(*insert)->parent->right = left_node;
}
left_node->right = (*insert);
(*insert)->parent = left_node;
}
void FixViolation(struct node **root, struct node **insert) {
struct node *parent_node, *grand_node;
while ((*insert != *root) && (BLACK != (*insert)->color) && (RED == (*insert)->parent->color)) {
parent_node = (*insert)->parent;
grand_node = (*insert)->parent->parent;
if (parent_node == grand_node->left) {
struct node *uncle_node = grand_node->right;
if (NULL != uncle_node && RED == uncle_node->color) {
grand_node->color = RED;
parent_node->color = uncle_node->color = BLACK;
*insert = grand_node;
}
else {
if (*insert == parent_node->right) {
RotateLeft(root, &parent_node);
*insert = parent_node;
parent_node = (*insert)->parent;
}
RotateRight(root, &grand_node);
int temp = parent_node->color;
parent_node->color = grand_node->color;
grand_node->color = temp;
*insert = parent_node;
}
}
else {
struct node *uncle_node = grand_node->left;
if (NULL != uncle_node && RED == uncle_node->color) {
grand_node->color = RED;
parent_node->color = uncle_node->color = BLACK;
*insert = grand_node;
}
else {
if (*insert == parent_node->left) {
RotateRight(root, &parent_node);
*insert = parent_node;
parent_node = (*insert)->parent;
}
RotateLeft(root, &grand_node);
int temp = parent_node->color;
parent_node->color = grand_node->color;
grand_node->color = temp;
*insert = parent_node;
}
}
}
(*root)->color = BLACK;
}
void Insert(struct node **root, int key) {
struct node *insert = NewNode(key);
if (NULL == insert) {
printf("Memory cannot be allocated.\n");
return;
}
*root = BSTInsert(root, &insert);
FixViolation(root, &insert);
}
void Inorder(struct node *root) {
if (NULL != root) {
Inorder(root->left);
printf("%d ", root->key);
Inorder(root->right);
}
}
int main() {
struct node *root = NULL;
for (int i = 0; i < 20; i++) {
Insert(&root, i + 1);
}
Inorder(root);
printf("\nRoot : %d\n", root->key);
return 0;
}
Aucun commentaire:
Enregistrer un commentaire