ํฐ์คํ ๋ฆฌ ๋ทฐ
์๋ฃ๊ตฌ์กฐ : Binary Search Tree
dirmathfl 2021. 1. 17. 10:23์ด์ง ํ์ ํธ๋ฆฌ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด, ๊ตฌ๊ธ์ ์ฌ๋ฌ ์ฝ๋๋ค์ ๋ณด์์ง๋ง, ๋ฐ์ดํฐ ํ์ ์ ์๊ด์์ด ์ฌ์ฉํ ์ ์๋ ์ฝ๋๋ ์์๋ค. ์ด์ ์ด์ง ๊ฒ์ ํธ๋ฆฌ์ ๋์ ์๋ฆฌ๋ ์ดํด๋ณด๋ค๋, ๊ตฌํ์ ์ค์ ์ผ๋ก ๊ธ์ ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค.
BST?
Binary search tree - Wikipedia
From Wikipedia, the free encyclopedia Jump to navigation Jump to search Data structure in tree form sorted for fast lookup A binary search tree of size 9 and depth 3, with 8 at the root. The leaves are not drawn. In computer science, a binary search tree (
en.wikipedia.org
์์ฃผ ๊ฐ๋ตํ๊ฒ BST(Binary Search Tree)
์ ๋ํด ์ค๋ช
ํ์๋ฉด, ๋ถ๋ชจ ๋
ธ๋(Parent Node)๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ ์์(Left Child)์ ๋ถ๋ชจ๋ณด๋ค ์์ ๊ฐ์ด๋ฉฐ ์ค๋ฅธ์ชฝ ์์(Right Child)์ ๋ถ๋ชจ๋ณด๋ค ํฐ ๊ฐ์ ๊ฐ์ง๋ค. ์์ ์ด์งํธ๋ฆฌ(Complete Binary Tree)
๊ฐ ๋ ๊ฒฝ์ฐ ํ์์ ํจ์จ์ฑ์ ๋์ผ ์ ์๋ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์ฝ๋
header
#ifndef BST_H
#define BST_H
typedef struct node {
struct node *left;
struct node *right;
char data[0];
} node_t;
typedef struct binary_tree {
node_t *root;
int count;
} bst_t;
bst_t *init_bst();
void free_bst(bst_t *);
void ins_bst(bst_t *, const void *, const void *, int, int (*)(const void *, const void *));
void del_bst(bst_t *, const void *, int, int (*)(const void *, const void *));
void *find_data_in_bst(bst_t *, const void *, int (*)(const void *, const void *));
void list_bst(bst_t *, void (*)(const void *));
#endif
ํธ๋ฆฌ์ ๊ฐ ๋
ธ๋๋ฅผ ๋ํ๋ด๋ ๊ตฌ์กฐ์ฒด์ธ node_t
๋ผ๋ ๊ตฌ์กฐ์ฒด๋ง์ผ๋ก๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค. ํ์ง๋ง root ๋
ธ๋๋ฅผ ํฌ์ธํ
ํ๋ bst_t
๊ตฌ์กฐ์ฒด๋ฅผ ํตํด, ๋ณด๋ค ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ ์ ์๊ณ count
๋ฅผ ํตํด ํ์ฌ ๋
ธ๋์ ์๋ฅผ ํ์ธํ ์ ์๋ค.
init
bst_t *init_bst()
{
bst_t *bst = (bst_t *)malloc(sizeof(bst_t));
if (bst == NULL) {
//error logging.
return NULL;
}
bst->root = NULL;
bst->count = 0;
return bst;
}
๋
ธ๋๋ค์ ๊ด๋ฆฌํ bst_t
๊ตฌ์กฐ์ฒด๋ ์์ ๊ฐ์ด ์ด๊ธฐํ ํ ์ ์๋ค.
free
static void free_node(node_t *node)
{
if (node != NULL) {
free_node(node->left);
free_node(node->right);
free(node);
}
}
void free_bst(bst_t *bst)
{
if (bst->root == NULL)
return;
free_node(bst->root);
free(bst);
}
init
์๋ ๋ฌ๋ฆฌ free
์์๋ ๋ชจ๋ ๋
ธ๋๋ฅผ ์ํํ๋ฉด์ ํด์ ํ์ฌ์ผ ํ๋ค.
insert
static node_t *init_node(const void *data, int data_size)
{
node_t *node= (node_t *)malloc(sizeof(node_t) + data_size);
if (node == NULL) {
// error logging.
return NULL;
}
node->left = node->right = NULL;
memcpy(node->data, data, data_size);
return node;
}
void ins_bst(bst_t *bst, const void *data, const void *key,
int data_size, int (*cmp_node)(const void *, const void *))
{
node_t *parent = NULL;
node_t *temp = NULL;
temp = bst->root;
while (temp) {
if (cmp_node(temp->data, key) == 0)
return;
parent = temp;
if (cmp_node(parent->data, key) > 0)
temp = parent->left;
else
temp = parent->right;
}
node_t *new = init_node(data, data_size);
if (parent) {
if (cmp_node(parent->data, key) > 0)
parent->left = new;
else
parent->right = new;
} else
bst->root = new;
bst->count++;
}
ํ์ฌ ์ฝ์
ํ๊ณ ์ ํ๋ ๊ฐ์ ๋ฐ๋ผ, ์ด๋ค ๋
ธ๋๋ฅผ parent
๋ก ํ์ฌ์ผ ํ๋์ง ํ์ํ๋ค. ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ํ์ํ parent
์ child
๊ฐ ๋๋ค. ๋ง์ฝ parent
๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด, root
๊ฐ ์๋ ์ํ์ด๋ค.
delete
void del_bst(bst_t *bst, const void *key, int data_size, int (*cmp_node)(const void *, const void *))
{
node_t *parent = NULL;
node_t *child = NULL;
node_t *temp = NULL;
if (bst->root == NULL)
return;
temp = bst->root;
while (temp != NULL && cmp_node(temp->data, key) != 0) {
parent = temp;
temp = (cmp_node(temp->data, key) > 0) ? parent->left : parent->right;
}
if (temp == NULL)
return;
if (temp->left == NULL && temp->right == NULL) {
if (parent) {
if (parent->left == temp)
parent->left = NULL;
else
parent->right = NULL;
} else
bst->root = NULL;
} else if (temp->left == NULL || temp->right == NULL) {
child = (temp->left != NULL) ? temp->left : temp->right;
if (parent) {
if (parent->left == temp)
parent->left = child;
else
parent->right = child;
} else
bst->root = child;
} else {
// succesor parent
node_t *s_parent = temp;
node_t *succesor = temp->right;
while (succesor->left != NULL) {
s_parent = succesor;
succesor = succesor->left;
}
if (s_parent->left == succesor)
s_parent->left = succesor->right;
else
s_parent->right = succesor->right;
memcpy(temp->data, succesor->data, data_size);
temp = succesor;
}
bst->count--;
free(temp);
}
delete
๋ ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ ๋นํด ๋ค์ ๋ณต์กํ๋ค. ์ด๋ 1) ์์์ด ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ, 2) ์์์ด ํ๋ ์กด์ฌํ๋ ๊ฒฝ์ฐ, 3) ์์์ด ๋ ์กด์ฌํ๋ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ ์์ ์ฝ๋๋ ์ญ์ ํ๊ณ ์ ํ๋ ๋
ธ๋์ ์์น๊น์ง ํ์ ํ, ์์์ ์กด์ฌ ์ฌ๋ถ์ ๋ฐ๋ผ ์ฒ๋ฆฌํ๋ ๊ฒ์ด๋ค.
find_data
void *find_data_in_bst(bst_t *bst, const void *key, int (*cmp_node)(const void *, const void *))
{
node_t *cur_node = bst->root;
int diff = 0;
while (cur_node) {
diff = cmp_node(cur_node->data, key);
if (diff == 0)
return cur_node->data;
else if (diff > 0)
cur_node = cur_node->left;
else
cur_node = cur_node->right;
}
return NULL;
}
root
๋ถํฐ ์์ฐจ์ ์ผ๋ก ํ์ํ์ฌ, ์ฐพ๊ณ ์ ํ๋ ๊ฐ์ด ์๋์ง ํ์ํ๋ค.
์ ์ฒด์ฝ๋
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "bst.h"
bst_t *init_bst()
{
bst_t *bst = (bst_t *)malloc(sizeof(bst_t));
if (bst == NULL) {
//error logging.
return NULL;
}
bst->root = NULL;
bst->count = 0;
return bst;
}
static void free_node(node_t *);
void free_bst(bst_t *bst)
{
if (bst->root == NULL)
return;
free_node(bst->root);
free(bst);
}
static node_t *init_node(const void *, int);
void ins_bst(bst_t *bst, const void *data, const void *key,
int data_size, int (*cmp_node)(const void *, const void *))
{
node_t *parent = NULL;
node_t *temp = NULL;
temp = bst->root;
while (temp) {
if (cmp_node(temp->data, key) == 0)
return;
parent = temp;
if (cmp_node(parent->data, key) > 0)
temp = parent->left;
else
temp = parent->right;
}
node_t *new = init_node(data, data_size);
if (parent) {
if (cmp_node(parent->data, key) > 0)
parent->left = new;
else
parent->right = new;
} else
bst->root = new;
bst->count++;
}
void del_bst(bst_t *bst, const void *key, int data_size, int (*cmp_node)(const void *, const void *))
{
node_t *parent = NULL;
node_t *child = NULL;
node_t *temp = NULL;
if (bst->root == NULL)
return;
temp = bst->root;
while (temp != NULL && cmp_node(temp->data, key) != 0) {
parent = temp;
temp = (cmp_node(temp->data, key) > 0) ? parent->left : parent->right;
}
if (temp == NULL)
return;
if (temp->left == NULL && temp->right == NULL) {
if (parent) {
if (parent->left == temp)
parent->left = NULL;
else
parent->right = NULL;
} else
bst->root = NULL;
} else if (temp->left == NULL || temp->right == NULL) {
child = (temp->left != NULL) ? temp->left : temp->right;
if (parent) {
if (parent->left == temp)
parent->left = child;
else
parent->right = child;
} else
bst->root = child;
} else {
// succesor parent
node_t *s_parent = temp;
node_t *succesor = temp->right;
while (succesor->left != NULL) {
s_parent = succesor;
succesor = succesor->left;
}
if (s_parent->left == succesor)
s_parent->left = succesor->right;
else
s_parent->right = succesor->right;
memcpy(temp->data, succesor->data, data_size);
temp = succesor;
}
bst->count--;
free(temp);
}
void *find_data_in_bst(bst_t *bst, const void *key, int (*cmp_node)(const void *, const void *))
{
node_t *cur_node = bst->root;
int diff = 0;
while (cur_node) {
diff = cmp_node(cur_node->data, key);
if (diff == 0)
return cur_node->data;
else if (diff > 0)
cur_node = cur_node->left;
else
cur_node = cur_node->right;
}
return NULL;
}
static void search_node(node_t *, void (*)(const void *));
void list_bst(bst_t *bst, void (*print_data)(const void *))
{
printf("cur_nodes : %d\n", bst->count);
if (bst->root == NULL)
return;
search_node(bst->root, print_data);
}
/* Private functions */
static node_t *init_node(const void *data, int data_size)
{
node_t *node= (node_t *)malloc(sizeof(node_t) + data_size);
if (node == NULL) {
// error logging.
return NULL;
}
node->left = node->right = NULL;
memcpy(node->data, data, data_size);
return node;
}
static void free_node(node_t *node)
{
if (node != NULL) {
free_node(node->left);
free_node(node->right);
free(node);
}
}
static void search_node(node_t *node, void (*print_data)(const void *))
{
if (node != NULL) {
search_node(node->left, print_data);
print_data(node->data);
search_node(node->right, print_data);
}
}
ํ ์คํธ
#include "bst.h"
#include <string.h>
#include <stdio.h>
typedef struct {
char name[32];
}info;
void init_info(info *t, const char *name)
{
memset(t, 0, sizeof(info));
memcpy(t->name, name, 32);
}
int cmp_name(const void *a, const void *b)
{
return strcmp(((info *)a)->name, ((char *)b));
}
void print_data(const void *a)
{
printf("%s\n", (char *)a);
}
int main()
{
info temp;
init_info(&temp, "TEST1");
bst_t *bst = init_bst();
ins_bst(bst, &temp, "TEST1", sizeof(info), cmp_name);
init_info(&temp, "TEST2");
ins_bst(bst, &temp, "TEST2", sizeof(info), cmp_name);
list_bst(bst, print_data);
printf("-----------\n");
info *test = (info *)find_data_in_bst(bst, "TEST2", cmp_name);
printf("%s\n", test->name);
printf("-----------\n");
del_bst(bst, "TEST2", sizeof(info), cmp_name);
list_bst(bst, print_data);
init_info(&temp, "TEST5");
ins_bst(bst, &temp, "TEST5", sizeof(info), cmp_name);
del_bst(bst, "TEST2", sizeof(info), cmp_name);
del_bst(bst, "TEST5", sizeof(info), cmp_name);
del_bst(bst, "TEST1", sizeof(info), cmp_name);
list_bst(bst, print_data);
free_bst(bst);
}

์์ ๊ฐ์ main ์์ ์ฝ๋๋ฅผ ํตํด, ๊ตฌํํ BST
์ init, insert, delete, find, search, free๊น์ง ๋ชจ๋ ๊ธฐ๋ฅ๋ค์ด ์ ์ ์๋ํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค. ์ฌ๊ท๋ฅผ ์ฌ์ฉํด, ๋ณด๋ค ๊ฐ๋จํ๊ฒ ๊ธฐ๋ฅ๋ค์ ์์ฑํ ์ ์๋ค. ํ์ง๋ง ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ์ฌ ๊ตฌํํจ์ผ๋ก์จ BST
๊ตฌํ๊ณผ ์๋ฆฌ์ ๋ํด ๋ณด๋ค ๋ช
ํํ๊ณ , ์ง๊ด์ ์ผ๋ก ์ดํดํ ์ ์์๋ค.
'๐๏ธโโ๏ธ ๊ธฐ๋ฐ ๋ค์ง๊ธฐ > ์๋ฃ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฃ๊ตฌ์กฐ: Hash (6) | 2021.01.10 |
---|---|
์๊ณ ๋ฆฌ์ฆ: ์ ๋ ฌ (0) | 2020.06.17 |
์๊ณ ๋ฆฌ์ฆ: DFS์ BFS (0) | 2020.06.16 |
์๊ณ ๋ฆฌ์ฆ: Recursion (0) | 2020.06.16 |
์๋ฃ๊ตฌ์กฐ: Linked List (0) | 2020.06.15 |