C-Programming/Datastructures/src/bst/bst.c

167 lines
3.2 KiB
C

/**
* Generic test class for implementing
* a simple binary search tree
* _ _ _ _
* __ ___ __(_) |_| |_ ___ _ __ | |__ _ _
* \ \ /\ / / '__| | __| __/ _ \ '_ \ | '_ \| | | |
* \ V V /| | | | |_| || __/ | | | | |_) | |_| |
* \_/\_/ |_| |_|\__|\__\___|_| |_| |_.__/ \__, |
* |___/
* ____ __ __ _
* / ___|_ _____ _ __ \ \ / /__ __ _ ___| |
* \___ \ \ / / _ \ '_ \ \ \ / / _ \ / _` |/ _ \ |
* ___) \ V / __/ | | | \ V / (_) | (_| | __/ |
* |____/ \_/ \___|_| |_| \_/ \___/ \__, |\___|_|
* |___/
* Licensed under the GPLv2 License, Version 2.0 (the "License");
* Copyright (c) Sven Vogel
*/
#include "bst.h"
#include <stdlib.h>
Bst bst_new() {
Bst bst = {
.root = NULL
};
return bst;
}
void dealloc_node(Node *node) {
if (node == NULL)
return;
dealloc_node(node->left);
dealloc_node(node->right);
free(node);
}
void bst_destroy(Bst *bst) {
dealloc_node(bst->root);
}
Node* new_node(char value) {
Node *n = (Node*) calloc(sizeof(Node), 1);
n->value = value;
return n;
}
void place_node(Node *node, char value) {
if (value > node->value) {
if (node->right == NULL) {
node->right = new_node(value);
return;
}
place_node(node->right, value);
} else {
if (node->left == NULL) {
node->left = new_node(value);
return;
}
place_node(node->left, value);
}
}
void bst_insert(Bst *bst, char value) {
if (bst->root == NULL) {
bst->root = new_node(value);
return;
}
place_node(bst->root, value);
}
bool search_node(Node* node, char value) {
if (value == node->value) {
return true;
}
if (value > node->value) {
if (node->right == NULL)
return false;
return search_node(node->right, value);
} else {
if (node->left == NULL)
return false;
return search_node(node->left, value);
}
}
bool bst_search(Bst *bst, char value) {
return search_node(bst->root, value);
}
Node** minimum(Node *node) {
if (node->left->left == NULL) {
return &node->left;
}
return minimum(node->left);
}
void remove_node(Node **node, char value) {
if (value > (*node)->value)
remove_node(&(*node)->right, value);
else if (value < (*node)->value)
remove_node(&(*node)->left, value);
else {
if ((*node)->right == (*node)->left) {
*node = NULL;
} else if ((*node)->left == NULL) {
*node = (*node)->right;
} else if ((*node)->right == NULL) {
*node = (*node)->left;
} else {
Node **min = minimum(*node);
(*node)->value = (*min)->value;
*min = NULL;
}
}
}
void bst_remove(Bst *bst, char value) {
if (bst->root == NULL)
return;
remove_node(&bst->root, value);
}
char node_max(Node *node) {
if (node->right == NULL)
return node->value;
return node_max(node->right);
}
char bst_max(Bst *bst) {
if (bst->root == NULL)
return '\0';
return node_max(bst->root);
}
char node_min(Node *node) {
if (node->left == NULL)
return node->value;
return node_min(node->left);
}
char bst_min(Bst *bst) {
if (bst->root == NULL)
return '\0';
return node_min(bst->root);
}