Моя цель состоит в том, чтобы реализовать красное черное дерево в C, и я считаю, что мой алгоритм корректен, но код, похоже, не работает для случаев 2 и 3 при вставке нового элемента
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TYPE int
#define RED 'r'
#define BLACK 'b'
typedef struct Node
{
TYPE data;
char colour;
struct Node *left;
struct Node *right;
struct Node *parent;
}Node;
Node *root = NULL;
Node *newNode(TYPE data);
Node *rotateLeft(Node *root,Node **x);
Node *rotateRight(Node *root,Node **x);
Node *bstInsert(Node *root,Node *n);
Node *rbtInsert(Node *root,TYPE data);
void rbtFix(Node *root,Node *n);
void inOrder(Node *root);
Node *minValueNode(Node *root);
Node *bstDelete(Node *root,TYPE data);
int main()
{
root = rbtInsert(root,5);
inOrder(root);
printf("\n");
rbtInsert(root,2);
inOrder(root);
printf("\n");
rbtInsert(root,1);
inOrder(root);
printf("\n");
rbtInsert(root,4);
inOrder(root);
printf("\n");
rbtInsert(root,7);
inOrder(root);
printf("\n");
rbtInsert(root,6);
inOrder(root);
printf("\n");
rbtInsert(root,10);
inOrder(root);
printf("\n");
printf("\n %c ",root->right->colour);
printf("\n %c ",root->left->colour);
printf("\n %c ",root->colour);
printf("\n %c ",root->right->right->colour);
return 0;
}
Node *rotateLeft(Node *root,Node **x)
{
Node *y;
y = (*x)->right; //Set y
(*x)->right = y->left; //Turn y’s left subtree into x’s right subtree
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;
return root;
}
Node *rotateRight(Node *root,Node **y)
{
Node *x;
x = (*y)->left; //Set x
(*y)->left = x->right; //Turn x's right Subtree into y's left Subtree
if (x->right != NULL)
x->right->parent = *y;
x->parent = (*y)->parent;
if((*y)->parent == NULL)
root = x;
else if((*y) == (*y)->parent->left)
(*y)->parent->left = x;
else
(*y)->parent->right = x;
x->right = (*y);
(*y)->parent = x;
return root;
}
Node *newNode(TYPE data)
{
Node *n = (Node*)malloc(sizeof(Node));
n->data = data;
n->colour = RED;
n->left = NULL;
n->right = NULL;
n->parent = NULL;
return n;
}
Node *bstInsert(Node *root,Node *n)
{
//if tree is empty
if (root == NULL)
return n;
//if tree is full
if (n->data < root->data)
{
root->left = bstInsert(root->left,n);
root->left->parent = root;
}
else if(n->data > root->data)
{
root->right = bstInsert(root->right,n);
root->right->parent = root;
}
return root;
}
Node *rbtInsert(Node *root,TYPE data)
{
Node *n = newNode(data);
root = bstInsert(root,n);
rbtFix(root,n);
return root;
}
void rbtFix(Node *root,Node *n)
{
while ((n != root)&&(n->colour == RED)&&(n->parent->colour == RED))
{
//if Parent is left of GrandParent
if(n->parent == n->parent->parent->left)
{
Node *Uncle = n->parent->parent->right;
//Case 1
if ((Uncle != NULL)&&(Uncle->colour == RED))
{
Uncle->colour = BLACK;
n->parent->colour = BLACK;
n->parent->parent->colour = RED;
n = n->parent->parent;
}
else
{
char temp = n->parent->colour;
n->parent->colour = n->parent->parent->colour;
n->parent->parent->colour = temp;
//Case 2
if (n == n->parent->right)
{
rotateLeft(root,&(n->parent));
}
//Case 3
rotateRight(root,&(n->parent->parent));
}
}
// if Parent is right of GrandParent
else if (n->parent == n->parent->parent->right)
{
Node *Uncle = n->parent->parent->left;
//Case 1
if ((Uncle != NULL)&&(Uncle->colour == RED))
{
Uncle->colour = BLACK;
n->parent->colour = BLACK;
n->parent->parent->colour = RED;
n = n->parent->parent;
}
else
{
char temp = n->parent->colour;
n->parent->colour = n->parent->parent->colour;
n->parent->parent->colour = temp;
//Case 2
if (n == n->parent->left)
{
rotateRight(root,&(n->parent));
}
//case 3
rotateLeft(root,&(n->parent->parent));
}
}
}
root->colour = BLACK;
}
void inOrder(Node *root)
{
if (root != NULL)
{
inOrder(root->left);
printf("%d\t",root->data);
inOrder(root->right);
}
}
Node *minValueNode(Node *root)
{
Node *min = root;
while (min->left != NULL)
min = min->left;
return min;
}
Node *bstDelete(Node *root,TYPE data)
{
//if Node not found
if (root == NULL)
return root;
//if data less than data of Node
if (data < root->data)
root->left = bstDelete(root->left,data);
//if data greater than data of Node
else if (data > root->data)
root->right = bstDelete(root->right,data);
//if data is equal to the data of Node then this Node is the one to be
deleted
else
{
// if node with no child or 1 child
if (root->left == NULL)
{
Node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
Node *temp = root->left;
free(root);
return temp;
}
//if Node has 2 children
Node *temp = minValueNode(root->right);
root->data = temp->data;
root->right = bstDelete(root->right,temp->data);
}
return root;
}
Я думаю, что указатель узла, который должен вращаться, должен вызываться по ссылке, а не по значению.
Должен ли я изменить все другие функции, такие как вращение, или это только для функции вращения