Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BasedOnStyle: Google
ColumnLimit: 160
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.12)

project(red-black-tree C)

add_library(${PROJECT_NAME} "")
target_sources(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/rbtree.c
INTERFACE
${CMAKE_CURRENT_LIST_DIR}/rbtree.h
)

target_include_directories(${PROJECT_NAME}
INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
202 changes: 72 additions & 130 deletions rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,22 @@

#include "rbtree.h"

t_rbnode *root_rbtree = (t_rbnode*)0;
t_rbnode *root_rbtree = (t_rbnode *)0;

static inline int is_red(t_rbnode *node)
{
return ((node) ? (node->color == RED) : (0));
}
static inline int is_red(t_rbnode *node) { return ((node) ? (node->color == RED) : (0)); }

static inline int my_compare(unsigned int key1, unsigned int key2)
{
return ((key1 == key2) ? (0) : ((key1 < key2) ? (-1) : (1)));
}
static inline int my_compare(unsigned int key1, unsigned int key2) { return ((key1 == key2) ? (0) : ((key1 < key2) ? (-1) : (1))); }

static void flip_color(t_rbnode *node)
{
static void flip_color(t_rbnode *node) {
node->color = !(node->color);
node->left->color = !(node->left->color);
node->right->color = !(node->right->color);
}

static t_rbnode *rotate_left(t_rbnode *left)
{
t_rbnode *right;
static t_rbnode *rotate_left(t_rbnode *left) {
t_rbnode *right;

if (!left)
return ((t_rbnode*)0);
if (!left) return ((t_rbnode *)0);
right = left->right;
left->right = right->left;
right->left = left;
Expand All @@ -43,12 +34,10 @@ static t_rbnode *rotate_left(t_rbnode *left)
return (right);
}

static t_rbnode *rotate_right(t_rbnode *right)
{
t_rbnode *left;
static t_rbnode *rotate_right(t_rbnode *right) {
t_rbnode *left;

if(!right)
return ((t_rbnode*)0);
if (!right) return ((t_rbnode *)0);
left = right->left;
right->left = left->right;
left->right = right;
Expand All @@ -57,182 +46,135 @@ static t_rbnode *rotate_right(t_rbnode *right)
return (left);
}

t_rbnode *create_node(t_key key,
t_value value)
{
t_rbnode *new;
t_rbnode *create_node(t_key key, t_value value) {
t_rbnode *new;

if ((new = (t_rbnode*)malloc(sizeof(*new))) == (t_rbnode*)0)
return ((t_rbnode*)0);
if ((new = (t_rbnode *)malloc(sizeof(*new))) == (t_rbnode *)0) return ((t_rbnode *)0);
new->key = key;
new->value = value;
new->color = RED;
new->left = (t_rbnode*)0;
new->right = (t_rbnode*)0;
new->left = (t_rbnode *)0;
new->right = (t_rbnode *)0;
return (new);
}

static t_rbnode *insert_this(t_rbnode *node, t_key key, t_value value)
{
int res;
static t_rbnode *insert_this(t_rbnode *node, t_key key, t_value value) {
int res;

if (!node)
return (create_node(key, value));
if (!node) return (create_node(key, value));
res = my_compare(key, node->key);
if (res == 0)
node->value = value;
else if (res < 0)
node->left = insert_this(node->left, key, value);
else
node->right = insert_this(node->right, key, value);
if (is_red(node->right) && !is_red(node->left))
node = rotate_left(node);
if (is_red(node->left) && is_red(node->left->left))
node = rotate_right(node);
if (is_red(node->left) && is_red(node->right))
flip_color(node);
if (is_red(node->right) && !is_red(node->left)) node = rotate_left(node);
if (is_red(node->left) && is_red(node->left->left)) node = rotate_right(node);
if (is_red(node->left) && is_red(node->right)) flip_color(node);
return (node);
}

void insert(t_key key, t_value value)
{
void insert(t_key key, t_value value) {
root_rbtree = insert_this(root_rbtree, key, value);
if (root_rbtree)
root_rbtree->color = BLACK;
if (root_rbtree) root_rbtree->color = BLACK;
}

t_value get_key(t_rbnode *node, t_key key)
{
int cmp;
t_value get_key(t_rbnode *node, t_key key) {
int cmp;

while (node)
{
if (!(cmp = my_compare(key, node->key)))
return (node->value);
while (node) {
if (!(cmp = my_compare(key, node->key))) return (node->value);
node = ((cmp < 0) ? (node->left) : (node->right));
}
return (0);
}

static t_rbnode *min(t_rbnode *node)
{
if (!node)
return ((t_rbnode*)0);
while (node->left)
node = node->left;
static t_rbnode *min(t_rbnode *node) {
if (!node) return ((t_rbnode *)0);
while (node->left) node = node->left;
return (node);
}

inline t_rbnode *balance_me_that(t_rbnode *node)
{
if (is_red(node->right))
node = rotate_left(node);
if (is_red(node->left) && is_red(node->left->left))
node = rotate_right(node);
if (is_red(node->left) && is_red(node->right))
flip_color(node);
inline t_rbnode *balance_me_that(t_rbnode *node) {
if (is_red(node->right)) node = rotate_left(node);
if (is_red(node->left) && is_red(node->left->left)) node = rotate_right(node);
if (is_red(node->left) && is_red(node->right)) flip_color(node);
return (node);
}

static t_rbnode *move_red_to_left(t_rbnode *node)
{
static t_rbnode *move_red_to_left(t_rbnode *node) {
flip_color(node);
if (node && node->right && is_red(node->right->left))
{
if (node && node->right && is_red(node->right->left)) {
node->right = rotate_right(node->right);
node = rotate_left(node);
flip_color(node);
}
return (node);
}

static t_rbnode *move_red_to_right(t_rbnode *node)
{
static t_rbnode *move_red_to_right(t_rbnode *node) {
flip_color(node);
if (node && node->left && is_red(node->left->left))
{
if (node && node->left && is_red(node->left->left)) {
node = rotate_right(node);
flip_color(node);
}
return (node);
}

static t_rbnode *remove_min(t_rbnode *node)
{
if (!node)
return ((t_rbnode*)0);
if (!node->left)
{
static t_rbnode *remove_min(t_rbnode *node) {
if (!node) return ((t_rbnode *)0);
if (!node->left) {
free(node);
return ((t_rbnode*)0);
return ((t_rbnode *)0);
}
if (!is_red(node->left) && !is_red(node->left->left))
node = move_red_to_left(node);
if (!is_red(node->left) && !is_red(node->left->left)) node = move_red_to_left(node);
node->left = remove_min(node->left);
return (balance_me_that(node));
}

static t_rbnode *remove_it(t_rbnode *node, t_key key)
{
t_rbnode *tmp;

if (!node)
return ((t_rbnode*)0);
if (my_compare(key, node->key) == -1)
{
if (node->left)
{
if (!is_red(node->left) && !is_red(node->left->left))
node = move_red_to_left(node);
static t_rbnode *remove_it(t_rbnode *node, t_key key) {
t_rbnode *tmp;

if (!node) return ((t_rbnode *)0);
if (my_compare(key, node->key) == -1) {
if (node->left) {
if (!is_red(node->left) && !is_red(node->left->left)) node = move_red_to_left(node);
node->left = remove_key(node->left, key);
}
}
else
{
if (is_red(node->left))
node = rotate_right(node);
if (!my_compare(key, node->key) && !node->right)
{
} else {
if (is_red(node->left)) node = rotate_right(node);
if (!my_compare(key, node->key) && !node->right) {
free(node);
return ((t_rbnode*)0);
return ((t_rbnode *)0);
}
if (node->right)
{
if (!is_red(node->right) && !is_red(node->right->left))
node = move_red_to_right(node);
if (!my_compare(key, node->key))
{
tmp = min(node->right);
node->key = tmp->key;
node->value = tmp->value;
node->right = remove_min(node->right);
}
else
node->right = remove_key(node->right, key);
if (node->right) {
if (!is_red(node->right) && !is_red(node->right->left)) node = move_red_to_right(node);
if (!my_compare(key, node->key)) {
tmp = min(node->right);
node->key = tmp->key;
node->value = tmp->value;
node->right = remove_min(node->right);
} else
node->right = remove_key(node->right, key);
}
}
return (balance_me_that(node));
}

t_rbnode *remove_key(t_rbnode *node, t_key key)
{
t_rbnode *remove_key(t_rbnode *node, t_key key) {
node = remove_it(node, key);
if (node)
node->color = BLACK;
if (node) node->color = BLACK;
return (node);
}

t_rbnode *erase_tree(t_rbnode *node)
{
if (node)
{
if (node->left)
erase_tree(node->left);
if (node->right)
erase_tree(node->right);
node->left = (t_rbnode*)0;
node->right = (t_rbnode*)0;
t_rbnode *erase_tree(t_rbnode *node) {
if (node) {
if (node->left) erase_tree(node->left);
if (node->right) erase_tree(node->right);
node->left = (t_rbnode *)0;
node->right = (t_rbnode *)0;
free(node);
}
return ((t_rbnode*)0);
return ((t_rbnode *)0);
}
47 changes: 21 additions & 26 deletions rbtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,32 @@
*/

#ifndef RBTREE_H_
# define RBTREE_H_
#define RBTREE_H_

# include <stddef.h>
# include <stdlib.h>
#include <stddef.h>
#include <stdlib.h>

typedef enum rbcolor
{
BLACK = 0,
RED = 1
} t_rbcolor;
typedef enum rbcolor { BLACK = 0, RED = 1 } t_rbcolor;

/*-------------------------------------------
** Modify these values according to the tree
**------------------------------------------*/
typedef unsigned int t_key;
typedef unsigned int t_value;

typedef struct s_rbnode
{
t_key key;
t_value value;
t_rbcolor color;
struct s_rbnode *left;
struct s_rbnode *right;

} t_rbnode;

t_rbnode *erase_tree(t_rbnode *node);
t_rbnode *remove_key(t_rbnode *node, t_key key);
unsigned int get_size(t_rbnode *node, t_key key);
t_value get_key(t_rbnode *node, t_key key);
void insert(t_key key, t_value value);
typedef unsigned int t_key;
typedef unsigned int t_value;

typedef struct s_rbnode {
t_key key;
t_value value;
t_rbcolor color;
struct s_rbnode *left;
struct s_rbnode *right;

} t_rbnode;

t_rbnode *erase_tree(t_rbnode *node);
t_rbnode *remove_key(t_rbnode *node, t_key key);
unsigned int get_size(t_rbnode *node, t_key key);
t_value get_key(t_rbnode *node, t_key key);
void insert(t_key key, t_value value);

#endif /* !RBTREE_H_ */
Loading