chapter 6. binary search trees internet computing kut youn-hee han
DESCRIPTION
1. Basic Concepts 무엇을 배우려고 하는가 ? (Motivation) Let’s first think just “Binary Search” Random array: sequential search Ex) finding 65 Sorted array: binary search found!! 1 st step 2 nd step 3 rd step rd step pivotTRANSCRIPT
Chapter 6. Binary Search Trees
Internet Computing Laboratory @ KUT
Youn-Hee Han
1. Basic Concepts무엇을 배우려고 하는가 ? (Motivation)
Sometimes, we want to search an arbitrary element efficiently.
Isn’t there any tree-based representation method for that situation?
Binary tree Binary search tree
1. Basic Concepts무엇을 배우려고 하는가 ? (Motivation)
Let’s first think just “Binary Search” Random array: sequential search
Ex) finding 65
Sorted array: binary search
35 38 70 75 12 25 18 54 65 90 86
found!!
1st step2nd step3rd step
12 18 25 35 38 54 65 70 75 86 90
4rd step
pivot
1. Basic ConceptsBinary search is more efficient than sequential search
Binary search is available for sorted array
Isn’t there a tree-based representation that has similar property with sorted array? BST (Binary Search Tree)
1. Basic ConceptsBinary search tree (BST): binary tree that is
All items in left subtree are less than the root All items in right subtree are greater than the root Each subtree itself is a binary search tree
BST 의 예
1. Basic Concepts
15
20
25
12 10 22
5
30
40
2
60
70
8055
Ex) Which is/are binary search tree(s)?
There is an efficient algorithm to find an arbitrary element
Ex) Find 20 from the following BST
1. Basic ConceptsBinary search vs. BST
A[0] A[1] A[2] x A[n-1]
found!!
1st step2nd step3rd step
root
< root > root
BST 는 “약하게 정렬되어 있다”라고 말할 수 있음
피벗 (Pivot) 을 중심으로 작은 것은 모두 왼쪽 , 큰 것은 모두 오른쪽
서브트리만 놓고 볼 때도 다시 파티션 된 상태이다
2. BST OperationsTraversal
Preorder 23 18 12 20 44 35 52
Postorder 12 20 18 35 52 44 23
Inoder 12 18 20 23 35 44 52
Which order produces a sequenced list? Inorder
Data Structure8
2. BST OperationsSearchs
Find the smallest node
Find the largest node
Data Structure9
Algorithm findSmallestBST (root)1. if (left subtree empty) 1. return (root)2. end if3. Return findSmallestBST (left subtree)end findSmallestBST
Algorithm findLargestBST (root)1. if (right subtree empty) 1. return (root)2. end if3. Return findLargestBST (right subtree)end findLargestBST
2. BST OperationsSearchs
Find an arbitrary element The most important feature of BST
Data Structure10
Algorithm searchBST (root, targetKey)1. if (empty tree) 1. return null2. end if3. if (targetKey < root) 1. return searchBST (left subtree, targetKey)4. else if (targetKey > root) 1. return searchBST (right subtree, targetKey)5. else 1. return root6. end ifend searchBST
2. BST OperationsSearchs
Find an arbitrary element What if SearchBST tries to find a value that does not exist
in the BST? Ex) Finding 25 from the following BST
Data Structure11
2. BST OperationsInsertion
Inserting a node into a BST preserving requirements of BST
삽입 할 새로운 노드는 Leaf Node 로서 들어감
Data Structure12
2. BST OperationsInsertion
Inserting Algorithm
Data Structure13
Algorithm addBST (root, newNode)1. if (empty tree) 1. set root to newNode 2. return newNode2. if (newNode < root) 1. return addBST (left subtree, newNode)3. else 1. return addBST (right subtree, newNode)4. end ifend addBST
30
30
30
30
2. BST OperationsDeletion
Case 1: the node has no children just delete it 부모노드의 자신을 가리키는 포인터를 Null 로 셋팅
Data Structure14
- 노드 A 삭제 부모노드 B 의 LChild 를 Null 로
셋팅 - 노드 K 삭제 부모노드 H 의 RChild 를 Null 로
셋팅
2. BST OperationsDeletion
Case 2: the node has only left subtree delete the node make the left child the new root ( 삭제되는 노드의 왼쪽 자식을 삭제되는 노드자리로 이동 )
Data Structure15
- 노드 F 삭제 F 의 부모노드 G 가 F 의 자식노드인 B 를 가리키면 됨
2. BST OperationsDeletion
Case 3: the node has only right subtree delete the node make the right child the new root ( 삭제되는 노드의 오른쪽 자식을 삭제되는 노드자리로 이동 )
Data Structure16
- 노드 L 삭제 L 의 부모노드 G 가 L 의 자식노드인 H 를 가리키면 됨
2. BST OperationsDeletion
Case 4: the node has both left and right children
Data Structure17
- 노드 B 를 삭제 노드 B 의 부모인 F 의 LChild 가 동시에 A 와 D 를 가리키게 ? 안되지… 노드 A 를 B 자리로 이동 ? 노드 D 를 B 자리로 이동 ? 둘다 가능하다 .
data copy
delete!
“ 이동” 에 대한 처리 : 1) 데이터만 실제 삭제하려는 노드로 Copy 2) 이동 대상 자체를 삭제 Deletion 을 다시 수행하므로 Recursion!
2. BST OperationsDeletion
Case 4: the node has both left and right children
Data Structure18
- 노드 G 를 삭제 우왕 복잡하다 ~~~~ 이진 탐색트리를 중위순회 (In-order Traversal) 한 결과를 생각 : A < B < D < F < G < H < K < L
G 가 삭제된 후에도 정렬된 순서를 그대로 유지하려면 G 의 자리에는 G 의 바로 오른쪽 H나 , 아니면 G 의 바로 왼쪽 F 가 들어가야 함 .
G 바로 다음에 나오는 H 를 G 의 중위 후속자 (In-order Successor) 라 하고 , G 바로 직전에 나오는 F 를 G 의 중위 선행자 (In-order Predecessor) 라고 함 .
그래서 , 결론적으로 G 에 대한 중위 후속자나 중위 선행자가 G 의 자리로 옮겨져야 한다 .
data copy
2. BST OperationsDeletion
Case 4: the node has both left and right children delete the node
replace it with the largest among left subtree or the smallest among the right subtree
Data Structure
Algorithm deleteBST (root, dltKey)1. if (empty tree) 1. return false2. end if3. if (dltKey < root) 1. return deleteBST (left subtree, dltKey)4. else if (delKey > root) 1. return deleteBST (right subtree, dltKey)5. else 1. if (no left subtree) 1. make right subtree the root 2. return true 2. if (no right subtree) 1. make left subtree the root 2. return true
15
20
25
12 27
2. BST OperationsDeletion
Case 4: the node has both left and right children delete the node
replace it with the largest among left subtree or the smallest among the right subtree
Data Structure
3. else 1. save root in deleteNode 2. set largest to largestBST(left subtree) 3. move data in largest to deleteNode 4. return deleteBST(left subtree, largest) 4. end if 5. end if
20
3. BST ADTBST ADT Design
Data Structure21
3. BST ADTData representation
Data Structure22
3. BST ADTCompare function (revisit)
Type-independent generic coding function pointer Compare operation
int (*compare)(void *argu1, void *argu2);
본 교재에서는 다음과 같이 return 값이 정의됨 Case I) argu1 의 데이터 > argu2 의 데이터 1 이 리턴됨 Case II) argu1 의 데이터 < argu2 의 데이터 -1 이 리턴됨 Case III) argu1 의 데이터 == argu2 의 데이터 0 이 리턴됨
Data Structure23
Algorithm searchBST (root, targetKey)…3. if (targetKey < root) 1. return searchBST (left subtree, targetKey)4. else if (targetKey > root) 1. return searchBST (right subtree, targetKey)…
3. BST ADTBST Declarations
File Name: bst.h ( 이후 모든 ADT 구현은 이 한 파일에 추가 )
Data Structure24
#include "stdbool.h"
typedef struct node { void* dataPtr; struct node* left; struct node* right;
} NODE;
typedef struct { int count; int (*compare) (void* argu1, void* argu2); NODE* root;
} BST_TREE;
BST_TREE* BST_Create (int (*compare) (void* argu1, void* argu2));BST_TREE* BST_Destroy (BST_TREE* tree);
3. BST ADTBST Declarations
File Name: bst.h
Data Structure25
bool BST_Insert (BST_TREE* tree, void* dataPtr);bool BST_Delete (BST_TREE* tree, void* dltKey);void* BST_Retrieve (BST_TREE* tree, void* keyPtr);void BST_Traverse (BST_TREE* tree, void (*process)(void* dataPtr));
bool BST_Empty (BST_TREE* tree);bool BST_Full (BST_TREE* tree);int BST_Count (BST_TREE* tree);
static NODE* _insert (BST_TREE* tree, NODE* root, NODE* newPtr); static NODE* _delete (BST_TREE* tree, NODE* root, void* dataPtr, bool* success);static void* _retrieve (BST_TREE* tree, void* dataPtr, NODE* root);static void _traverse (NODE* root, void (*process) (void* dataPtr));static void _destroy (NODE* root);
3. BST ADTCreate BST
Data Structure26
BST_TREE* BST_Create (int (*compare) (void* argu1, void* argu2)) { BST_TREE* tree;
tree = (BST_TREE*) malloc (sizeof (BST_TREE));
if (tree) { tree->root = NULL; tree->count = 0; tree->compare = compare; } return tree;}
3. BST ADTInsert BST
Data Structure27
bool BST_Insert (BST_TREE* tree, void* dataPtr) { NODE* newPtr; newPtr = (NODE*)malloc(sizeof(NODE));
if (!newPtr) return false;
newPtr->right = NULL; newPtr->left = NULL; newPtr->dataPtr = dataPtr; if (tree->count == 0) tree->root = newPtr; else _insert(tree, tree->root, newPtr);
(tree->count)++; return true;}
3. BST ADTInternal Insert BST
Data Structure28
NODE* _insert (BST_TREE* tree, NODE* root, NODE* newPtr) { if (!root) // Base Case return newPtr; // root 가 null 이면 return 되는 것은 newPtr if (tree->compare(newPtr->dataPtr, root->dataPtr) < 0) { root->left = _insert(tree, root->left, newPtr); } else { root->right = _insert(tree, root->right, newPtr); } return root; // root 가 null 이 아닐 때 return 되는 것은 단순히 root}
20
25
20
25
2222
추가하려는 노드
20
25
추가하려는 노드
20
25
3. BST ADTDelete BST
Data Structure29
bool BST_Delete (BST_TREE* tree, void* dltKey) { bool success; NODE* newRoot;
newRoot = _delete (tree, tree->root, dltKey, &success); if (success) { tree->root = newRoot; (tree->count)--; if (tree->count == 0) tree->root = NULL; } return success;}
3. BST ADTInternal Delete BST
Data Structure30
NODE* _delete (BST_TREE* tree, NODE* root, void* dataPtr, bool* success) { NODE* dltPtr; // 삭제되어질 root 노드의 임시 저장소 NODE* exchPtr; // the largest node among left subtree NODE* newRoot; // 삭제되어질 root 대신의 역할을 담당하게 될 노드 void* holdPtr; // 교환 작업을 위한 임시 저장소
if (!root) { // 삭제될 것이 검색이 안된 경우 *success = false; return NULL; }
if (tree->compare(dataPtr, root->dataPtr) < 0) root->left = _delete (tree, root->left, dataPtr, success); else if (tree->compare(dataPtr, root->dataPtr) > 0) root->right = _delete (tree, root->right, dataPtr, success);
3. BST ADTInternal Delete BST
Data Structure31
else { dltPtr = root; free (root->dataPtr); // data memory de-allocation
if (!root->left) { // root 의 왼쪽 자식이 null 이거나 // root 자체가 leaf 노드일 때
newRoot = root->right; free (dltPtr); *success = true; return newRoot; // base case
} else if (!root->right) { // root 의 왼쪽 자식은 null 이 아니고
// root 의 오른쪽 자식만 null 일 때 , newRoot = root->left; free (dltPtr); *success = true; return newRoot; // base case
Case I
Case II
Case ICase I
Case II
3. BST ADTInternal Delete BST
Data Structure32
} else { // Find the lowest node on right subtree exchPtr = root->right; while (exchPtr->left) exchPtr = exchPtr->left;
// Exchange Data holdPtr = root->dataPtr; root->dataPtr = exchPtr->dataPtr; exchPtr->dataPtr = holdPtr; // Delete the largest node root->right = _delete (tree, root->right, exchPtr->dataPtr, success); } } return root; }
3. BST ADTRetrieve BST
Data Structure33
void* BST_Retrieve (BST_TREE* tree, void* keyPtr) { if (tree->root) return _retrieve (tree, keyPtr, tree->root); else return NULL;}
void* _retrieve (BST_TREE* tree, void* dataPtr, NODE* root) { if (root) { if (tree->compare(dataPtr, root->dataPtr) < 0) return _retrieve(tree, dataPtr, root->left); else if (tree->compare(dataPtr, root->dataPtr) > 0) return _retrieve(tree, dataPtr, root->right); else return root->dataPtr; } else return NULL;}
3. BST ADTTraverse BST (inorder)
Data Structure34
void BST_Traverse (BST_TREE* tree, void (*process) (void* dataPtr)) { _traverse (tree->root, process); return;}
void _traverse (NODE* root, void (*process) (void* dataPtr)) { if (root) { _traverse (root->left, process); process (root->dataPtr); _traverse (root->right, process); } return;}
3. BST ADTEmpty, Full, Count BST
Data Structure35
bool BST_Empty (BST_TREE* tree) { return (tree->count == 0);}
bool BST_Full (BST_TREE* tree) { NODE* newPtr; newPtr = (NODE*)malloc(sizeof (*(tree->root))); if (newPtr) { free (newPtr); return false; } else return true;}
int BST_Count (BST_TREE* tree) { return (tree->count);}
3. BST ADTDestroy BST
Data Structure36
BST_TREE* BST_Destroy (BST_TREE* tree) { if (tree) _destroy (tree->root); free (tree); return NULL;}
void _destroy (NODE* root) { if (root) { _destroy (root->left); free (root->dataPtr); _destroy (root->right); free (root); } return;}
4. BST ApplicationInteger Application
BST Creation reads integers from the keyboard and inserts them into
the BST reads integers from the keyboard and deletes them from
the BST If BST is empty, the application comes to the end
Data Structure37
#ifndef _STDBOOL_H#define _STDBOOL_H
typedef int _Bool;
#define bool _Bool#define true 1#define false 0#define __bool_true_false_are_defined 1
#endif
stdbool.h
4. BST ApplicationInteger Application (BST_INT.c)
Data Structure38
#include <stdio.h>#include <stdlib.h>#include "bst.h"#include "stdbool.h"
int compareInt (void* num1, void* num2);void printBST (void* num1);
int main (void) { BST_TREE* BSTRoot; int* dataPtr; int dataIn = 1;
printf("Begin BST Demonstation\n");
BSTRoot = BST_Create (compareInt);
printf("Enter a list of positive integers;\n"); printf("Enter a negative number to stop.\n");
4. BST ApplicationInteger Application (BST_INT.c)
Data Structure39
do { printf("Enter a number: "); scanf ("%d", &dataIn); if (dataIn > -1) { dataPtr = (int*) malloc (sizeof (int)); if (!dataPtr) { printf("Memory Overflow in add\n"); exit(100); } *dataPtr = dataIn; BST_Insert (BSTRoot, dataPtr); } } while (dataIn > -1);
printf("\nBST contains:\n"); BST_Traverse (BSTRoot, printBST);
4. BST ApplicationInteger Application (BST_INT.c)
Data Structure40
while (!BST_Empty(BSTRoot)) { printf("\nEnter an integers to be deleted;\n"); printf("Enter a number: "); scanf ("%d", &dataIn); if (!BST_Delete(BSTRoot, &dataIn)) printf("ERROR: No Number: $d\n", dataIn);
printf("\nBST contains:\n"); BST_Traverse (BSTRoot, printBST); }
printf("\nEnd BST Demonstration\n"); return 0;}
4. BST ApplicationInteger Application (BST_INT.c)
Data Structure41
int compareInt (void* num1, void* num2) { int key1; int key2;
key1 = *(int*)num1; key2 = *(int*)num2; if (key1 < key2) return -1; if (key1 == key2) return 0; return +1;}
void printBST (void* num1) { printf("%4d\n", *(int*)num1); return;}