Binary search tree
Jump to navigation
Jump to search
Overview
이진 탐색 트리(BST: Binary search tree) 내용 정리
Basic
BST 는 다음과 같은 속성이 있는 이진 트리 자료 구조 이다.
- 각 노드에 값이 있다.
- 각 노드의 키 값은 모두 달라야 한다.
- 값 들은 전순서(totally ordered set-toset: 임의의 두 원소를 비교할 수 있는 부분 순서 집합)가 있다.
- 노드의 왼쪽 서브트리에는 그 노드의 값보다 작은 값들을 지닌 노드들로 이루어져 있다.
- 노드의 오른쪽 서브트리에는 그 노드의 값보다 큰 값들을 지닌 노드들로 이루어져 있다.
- 좌우 하위 트리는 각각이 다시 이진 탐색 트리여야 한다.
- 중복된 노드가 없어야 한다.
Search
- 이진 탐색 트리에서 키 X 를 가진 노드를 검색하고자 할 때, 트리에 해당 노드가 존재하면 해당 노드를 리턴하고, 존재하지 않으면 NULL 을 리턴한다.
- 검색하고자 하는 값을 루트 노드와 먼저 비교하고, 일치할 경우 루트노드를 리턴한다.
- 불일치하고 검색하고자 하는 값이 루트 노드보다 작을 경우 왼쪽 서브트리에서 재귀적으로 검색한다.
- 불일치하고 검색하고자 하는 값이 루트 노드보다 클 경우 오른쪽 서브트리에서 재귀적으로 검색한다.
Insert
- 삽입을 하기 전 검색을 수행한다.
- 트리를 검색한 후 일치하는 노드가 없으면 마지막 노드에서 키와 노드의 크리를 비교해서 왼쪽이나 오른쪽에 새로운 노드를 삽입한다.
Delete
삭제하려는 노드의 자식 수에 따라..
- 자식 노드가 없는 노드(리프 노드) 삭제: 해당 노드를 단순히 삭제한다.
- 자식 노드가 1개인 노드 삭제: 해당 노드를 삭제하고 그 위치에 해당 노드의 자식 노드를 대입한다.
- 자식 노드가 2개인 노드 삭제: 삭제하고자 하는 노드의 값을 해당 노드의 왼쪽 서브트리에서 가장 큰 값으로 대체하거나, 오른쪽 서브트리에서 가장 작은 값으로 대체한 뒤, 해당 노드(왼쪽 서브 트리에서 가장 큰 값을 가지는 노드 또는 오른쪽 서브트리에서 가장 작은 값을 가지는 노드)를 삭제한다.
Examples
C
<source lang=c>
- include <stdio.h>
- include <stdlib.h>
struct bst_node {
int value; struct bst_node* left; struct bst_node* right;
};
struct bst_node* create_node(int value) {
struct bst_node* node; node = calloc(1, sizeof(struct bst_node)); node->left = NULL; node->right = NULL; node->value = value; return node;
}
void release_node(struct bst_node* node) {
free(node); return;
}
void release_nodes(struct bst_node* node) {
if(node == NULL) { return; } release_nodes(node->left); release_nodes(node->right); release_node(node);
}
void insert_node(struct bst_node* root, int value) {
if(root == NULL) { fprintf(stderr, "Wrong input parameter.\n"); return; } if(value < root->value) { if(root->left == NULL) { root->left = create_node(value); return; } else { insert_node(root->left, value); return; } } else if(value > root->value) { if(root->right == NULL) { root->right = create_node(value); return; } else { insert_node(root->right, value); return; } } else { // should not reach to here. fprintf(stderr, "Something was wrong. Should not reach to here.\n"); return; } // should not reach to here. fprintf(stderr, "Something was wrong. Should not reach to here.\n"); return;
}
static struct bst_node* find_minimum(struct bst_node* root) {
if(root->left == NULL) { return root; } return find_minimum(root->left);
}
struct bst_node* delete_node(struct bst_node* root, int value)
{
struct bst_node* node_tmp; if(root == NULL) { return NULL; } if(value < root->value) { root->left = delete_node(root->left, value); } else if(value > root->value) { root->right = delete_node(root->right, value); } else { // found node. delete it. if((root->left == NULL) && (root->right == NULL)) { release_node(root); return NULL; } else if(root->left == NULL) { release_node(root); return root->right; } else if(root->right == NULL) { release_node(root); return root->left; } else { // node has two children node_tmp = find_minimum(root->right); root->value = node_tmp->value; root->right = delete_node(root->right, node_tmp->value); } } return root;
}
struct bst_node* search_node(struct bst_node* root, int value) {
if(root == NULL) { fprintf(stdout, "Could not find node.\n"); return NULL; } if(value == root->value) { return root; } else if(value < root->value) { return search_node(root->left, value); } else if(value > root->value) { return search_node(root->right, value); } // should not reach to here fprintf(stderr, "Should not reach to here. Something was wrong.\n"); return NULL;
}
int get_height(struct bst_node* root) {
int height_left; int height_right; if(root == NULL) { return 0; } height_left = get_height(root->left); height_right = get_height(root->right); if(height_left > height_right) { return (height_left + 1); } else { return height_right + 1; } // should not reach to here. fprintf(stderr, "Should not reach to here. Something was wrong.\n"); return -1;
}
void print_given_level(struct bst_node* root, int level) {
if((root == NULL) || (level < 0)) { return; } if(level == 1) { printf("%d ", root->value); } print_given_level(root->left, level - 1); print_given_level(root->right, level -1); return;
}
void print_level_order(struct bst_node* root) {
int height; int i; height = get_height(root); for(i = 1; i <= height; i++) { print_given_level(root, i); printf("\n"); } return;
}
int main(int argc, char** argv) {
struct bst_node* root; struct bst_node* node_tmp; root = NULL; root = create_node(5); insert_node(root, 3); insert_node(root, 2); insert_node(root, 4); insert_node(root, 7); insert_node(root, 6); insert_node(root, 8);
print_level_order(root); node_tmp = search_node(root, 4); if(node_tmp == NULL) { printf("Could not find node info.\n"); } else { printf("Found node. value[%d]\n", node_tmp->value); }
node_tmp = search_node(root, 9); if(node_tmp == NULL) { printf("Could not find node info.\n"); } else { printf("Found node. value[%d]\n", node_tmp->value); }
delete_node(root, 3); print_level_order(root); release_nodes(root); return 0;
} </source>