1. Makefile
.PHONY: clean
CC = gcc
CFLAGS = -g -Wall -DDEBUG -std=c99
SOURCE = $(wildcard ./*.c)
BIN = $(patsubst %.c, %, $(notdir $(SOURCE)))
$(BIN): $(SOURCE)
$(CC) $(CFLAGS) $(SOURCE) -o $@
clean:
rm -rf $(BIN)
2. binary_search_tree.h
#ifndef __BINARY_SEARCH_TREE_H__
#define __BINARY_SEARCH_TREE_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int binary_search_tree_data_t;
typedef struct binary_search_tree_s {
binary_search_tree_data_t data;
struct binary_search_tree_s *left;
struct binary_search_tree_s *right;
} binary_search_tree_t;
bool binary_search_tree_insert_data(binary_search_tree_t **root,
binary_search_tree_data_t data);
bool binary_search_tree_insert_data_recursion(binary_search_tree_t **root,
binary_search_tree_data_t data);
binary_search_tree_t *binary_search_tree_find_data(
const binary_search_tree_t *root,
binary_search_tree_data_t data);
binary_search_tree_t *binary_search_tree_find_data_recursion(
const binary_search_tree_t *root,
binary_search_tree_data_t data);
bool binary_search_tree_remove_data(binary_search_tree_t **root,
binary_search_tree_data_t data);
bool binary_search_tree_remove_data_recursion(binary_search_tree_t **root,
binary_search_tree_data_t data);
void binary_search_tree_in_order_recursion(const binary_search_tree_t *root);
void destroy_binary_search_tree(binary_search_tree_t **root);
#ifdef __cplusplus
}
#endif
#endif
3. binary_search_tree.c
#include "binary_search_tree.h"
static binary_search_tree_t *create_binary_search_tree(binary_search_tree_data_t data)
{
binary_search_tree_t *new_binary_search_tree = NULL;
do {
new_binary_search_tree = (binary_search_tree_t *)calloc(
1, sizeof(binary_search_tree_t));
if (NULL == new_binary_search_tree) {
perror("calloc new_binary_search_tree fail");
break;
}
new_binary_search_tree->data = data;
new_binary_search_tree->left = new_binary_search_tree->right = NULL;
} while (0);
return new_binary_search_tree;
}
bool binary_search_tree_insert_data(binary_search_tree_t **root,
binary_search_tree_data_t data)
{
if (NULL == *root) {
*root = create_binary_search_tree(data);
return NULL != *root;
}
binary_search_tree_t *cur = *root;
binary_search_tree_t *parent = NULL;
while (NULL != cur) {
parent = cur;
if (data == cur->data) {
return false;
} else if (data < cur->data) {
cur = cur->left;
} else {
cur = cur->right;
}
}
if (data < parent->data) {
parent->left = create_binary_search_tree(data);
} else if (data > parent->data) {
parent->right = create_binary_search_tree(data);
}
return true;
}
bool binary_search_tree_insert_data_recursion(binary_search_tree_t **root,
binary_search_tree_data_t data)
{
if (NULL == *root) {
*root = create_binary_search_tree(data);
return NULL != *root;
}
if (data == (*root)->data) {
return false;
} else if (data < (*root)->data) {
return binary_search_tree_insert_data_recursion(&((*root)->left), data);
} else {
return binary_search_tree_insert_data_recursion(&((*root)->right), data);
}
}
binary_search_tree_t *binary_search_tree_find_data(
const binary_search_tree_t *root,
binary_search_tree_data_t data)
{
if (NULL == root) {
return NULL;
}
binary_search_tree_t *cur = (binary_search_tree_t *)root;
while (NULL != cur) {
if (data == cur->data) {
return cur;
} else if (data < cur->data) {
cur = cur->left;
} else {
cur = cur->right;
}
}
return NULL;
}
binary_search_tree_t *binary_search_tree_find_data_recursion(
const binary_search_tree_t *root,
binary_search_tree_data_t data)
{
if (NULL == root || data == root->data) {
return (binary_search_tree_t *)root;
}
if (data < root->data) {
return binary_search_tree_find_data_recursion(root->left, data);
} else {
return binary_search_tree_find_data_recursion(root->right, data);
}
}
bool binary_search_tree_remove_data(binary_search_tree_t **root,
binary_search_tree_data_t data)
{
binary_search_tree_t *cur = *root;
binary_search_tree_t *parent = NULL;
while (NULL != cur) {
if (data == cur->data) {
if (NULL == cur->left) {
if (cur != *root) {
if (cur == parent->left) {
parent->left = cur->right;
} else {
parent->right = cur->right;
}
} else {
*root = cur->right;
}
free(cur);
} else if (NULL == cur->right) {
if (cur != *root) {
if (cur == parent->left) {
parent->left = cur->left;
} else {
parent->right = cur->left;
}
} else {
*root = cur->left;
}
free(cur);
} else {
binary_search_tree_t *min_right = cur->right;
binary_search_tree_t *min_right_parent = cur;
while (NULL != min_right->left) {
min_right_parent = min_right;
min_right = min_right->left;
}
cur->data = min_right->data;
if (min_right != min_right_parent->left) {
min_right_parent->right = min_right->right;
} else {
min_right_parent->left = min_right->right;
}
free(min_right);
}
return true;
} else {
parent = cur;
}
if (data < cur->data) {
cur = cur->left;
} else {
cur = cur->right;
}
}
return false;
}
bool binary_search_tree_remove_data_recursion(binary_search_tree_t **root,
binary_search_tree_data_t data)
{
if (NULL == root) {
return false;
}
if (data < (*root)->data) {
return binary_search_tree_remove_data_recursion(
&((*root)->left), data);
} else if (data > (*root)->data) {
return binary_search_tree_remove_data_recursion(
&((*root)->right), data);
} else {
if (NULL == (*root)->left) {
binary_search_tree_t *tmp = *root;
*root = (*root)->right;
free(tmp);
} else if (NULL == (*root)->right) {
binary_search_tree_t *tmp = *root;
*root = (*root)->left;
free(tmp);
} else {
binary_search_tree_t *min_right = (*root)->right;
while (NULL != min_right->left) {
min_right = min_right->left;
}
(*root)->data = min_right->data;
binary_search_tree_remove_data_recursion(&((*root)->right), min_right->data);
}
return true;
}
}
void binary_search_tree_in_order_recursion(const binary_search_tree_t *root)
{
if (NULL != root) {
binary_search_tree_in_order_recursion(root->left);
printf("%d ", root->data);
binary_search_tree_in_order_recursion(root->right);
}
}
void destroy_binary_search_tree(binary_search_tree_t **root)
{
if (NULL == *root) {
return;
}
destroy_binary_search_tree(&((*root)->left));
destroy_binary_search_tree(&((*root)->right));
free(*root);
*root = NULL;
}
4. test_binary_search_tree.c
#include "binary_search_tree.h"
void test()
{
binary_search_tree_t *root = NULL;
int i = 0;
printf("Insert data to binary search tree\n");
if (!binary_search_tree_insert_data(&root, 5)) {
printf("binary_search_tree_insert_data 5 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data(&root, 2)) {
printf("binary_search_tree_insert_data 2 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data(&root, 3)) {
printf("binary_search_tree_insert_data 3 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data(&root, 8)) {
printf("binary_search_tree_insert_data 8 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data(&root, 9)) {
printf("binary_search_tree_insert_data 9 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data(&root, 5)) {
printf("binary_search_tree_insert_data 5 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data_recursion(&root, 1)) {
printf("binary_search_tree_insert_data_recursion 1 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data_recursion(&root, 7)) {
printf("binary_search_tree_insert_data_recursion 7 failed(line: %d)\n", __LINE__);
}
if (!binary_search_tree_insert_data_recursion(&root, 5)) {
printf("binary_search_tree_insert_data_recursion 5 failed(line: %d)\n", __LINE__);
}
printf("in_order binary_search_tree(recursion):\n");
binary_search_tree_in_order_recursion(root);
printf("\n\nFind data (0 ~ 9):\n");
for (i = 0; i < 10; i++) {
binary_search_tree_t *found = binary_search_tree_find_data(root, i);
printf("data: %d, find result : %s\n", i, found ? "found" : "not found");
}
printf("\n\nFind data recursion (0 ~ 9):\n");
for (i = 0; i < 10; i++) {
binary_search_tree_t *found = binary_search_tree_find_data_recursion(root, i);
printf("data: %d, find result : %s\n", i, found ? "found" : "not found");
}
printf("\nDelete data to binary search tree\n");
printf("\nRemove 2\n");
if (!binary_search_tree_remove_data(&root, 2)) {
printf("binary_search_tree_remove_data 2 failed(line: %d)\n", __LINE__);
}
printf("in_order binary_search_tree(recursion):\n");
binary_search_tree_in_order_recursion(root);
printf("\nRemove 66\n");
if (!binary_search_tree_remove_data(&root, 66)) {
printf("binary_search_tree_remove_data 66 failed(line: %d)\n", __LINE__);
}
printf("in_order binary_search_tree(recursion):\n");
binary_search_tree_in_order_recursion(root);
printf("\nRemove 5\n");
if (!binary_search_tree_remove_data_recursion(&root, 5)) {
printf("binary_search_tree_remove_data_recursion 5 failed(line: %d)\n", __LINE__);
}
printf("in_order binary_search_tree(recursion):\n");
binary_search_tree_in_order_recursion(root);
printf("\ndestroy_binary_search_tree\n");
destroy_binary_search_tree(&root);
printf("in_order binary_search_tree(recursion):\n");
binary_search_tree_in_order_recursion(root);
}
int main(void)
{
test();
return 0;
}