|
| 1 | +# 이진탐색트리 (Binary Search Tree) |
| 2 | + |
| 3 | +## 정의 |
| 4 | + |
| 5 | +``` |
| 6 | +
|
| 7 | +이진탐색트리는 이진탐색(binary search)과 연결리스트(linked list)를 결합한 자료구조로 모든 노드의 왼쪽 서브트리는 |
| 8 | +해당 노드의 값보다 작은 값들만 가지고 모든 노드의 오른쪽 서브 트리는 해당 노드의 값보다 큰 값들만 가집니다. |
| 9 | + |
| 10 | +이진탐색의 효율적인 탐색 능력을 유지하면서도, 빈번한 자료 입력과 삭제를 가능하게끔 고안됐습니다. |
| 11 | +이진탐색(binary search) |
| 12 | +배열의 중간에 있는 임의의 값을 선택하여 찾고자 하는 값 X와 비교한다. |
| 13 | +X가 중간 값보다 작으면 중간 값을 기준으로 좌측의 데이터들을 대상으로, X가 중간값보다 크면 배열의 우측을 대상으로 다시 탐색한다. |
| 14 | +이러한 과정으로 값을 찾을 때 까지 계속 반복한다. |
| 15 | +
|
| 16 | +연결리스트(linked list) |
| 17 | +각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료 구조이다. |
| 18 | +
|
| 19 | +예컨대 이진탐색의 경우 탐색에 소요되는 시간복잡도는 𝑂(logN ) |
| 20 | +으로 빠르지만 자료 입력, 삭제가 불가능합니다. 연결리스트의 경우 자료 입력, 삭제에 필요한 시간복잡도는 𝑂(1)로 효율적이지만 최악의 경우 탐색하는 데에는 𝑂(N) |
| 21 | +의 시간복잡도가 발생합니다. |
| 22 | +
|
| 23 | +``` |
| 24 | + |
| 25 | +## 최악의 경우 (worst case) |
| 26 | + |
| 27 | +``` |
| 28 | +
|
| 29 | +이진 탐색 트리는 들어오는 순서대로 노드의 큰, 값 작은 값을 찾아 넣게 됩니다. 이런 경우에는 균형이 맞지 않는데, |
| 30 | + 예를 들면 n개의 노드가 크기 순으로 일렬로 늘어져 있는 경우 높이 또한 n이 되는 경우에는 시간복잡도가 O(n)입니다. |
| 31 | +이렇게 들어가는 값에 의한 정렬을 보안하기 위해 자가 이진트리인 AVL Tree, Red-Black Tree를 사용합니다. |
| 32 | +
|
| 33 | +``` |
| 34 | + |
| 35 | + |
| 36 | +## 구현 |
| 37 | + |
| 38 | +```java |
| 39 | + |
| 40 | +public class BinarySearchTree { |
| 41 | + Node root; |
| 42 | + |
| 43 | + public BinarySearchTree() { |
| 44 | + this.root = null; |
| 45 | + } |
| 46 | + |
| 47 | + public void insert(int value) { |
| 48 | + this.root = insertHelper(this.root, value); |
| 49 | + } |
| 50 | + |
| 51 | + private Node insertHelper(Node root, int value) { |
| 52 | + if (root == null) { |
| 53 | + root = new Node(value); |
| 54 | + return root; |
| 55 | + } |
| 56 | + |
| 57 | + if (value < root.value) { |
| 58 | + root.leftChild = insertHelper(root.leftChild, value); |
| 59 | + } else if (value > root.value) { |
| 60 | + root.rightChild = insertHelper(root.rightChild, value); |
| 61 | + } |
| 62 | + |
| 63 | + return root; |
| 64 | + } |
| 65 | + |
| 66 | + public boolean search(int value) { |
| 67 | + return searchHelper(this.root, value); |
| 68 | + } |
| 69 | + |
| 70 | + private boolean searchHelper(Node root, int value) { |
| 71 | + if (root == null) { |
| 72 | + return false; |
| 73 | + } |
| 74 | + |
| 75 | + if (root.value == value) { |
| 76 | + return true; |
| 77 | + } else if (value < root.value) { |
| 78 | + return searchHelper(root.leftChild, value); |
| 79 | + } else { |
| 80 | + return searchHelper(root.rightChild, value); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + public void inorderTraversal() { |
| 85 | + inorderTraversalHelper(this.root); |
| 86 | + } |
| 87 | + |
| 88 | + private void inorderTraversalHelper(Node root) { |
| 89 | + if (root != null) { |
| 90 | + inorderTraversalHelper(root.leftChild); |
| 91 | + System.out.print(root.value + " "); |
| 92 | + inorderTraversalHelper(root.rightChild); |
| 93 | + } |
| 94 | + } |
| 95 | +} |
| 96 | + |
| 97 | +class Node { |
| 98 | + int value; |
| 99 | + Node leftChild; |
| 100 | + Node rightChild; |
| 101 | + |
| 102 | + public Node(int value) { |
| 103 | + this.value = value; |
| 104 | + this.leftChild = null; |
| 105 | + this.rightChild = null; |
| 106 | + } |
| 107 | +} |
| 108 | + |
| 109 | +``` |
| 110 | + |
| 111 | +# AVLTree |
| 112 | + |
| 113 | +``` |
| 114 | +
|
| 115 | +AVL트리는 트리가 한쪽으로 치우쳐 자라나는 현상을 방지하여 트리 높이의 균형을 유지하는 이진탐색트리이다. |
| 116 | +Balanced 이진탐색트리를 만들면 N개의 노드를 가진 트리의 높이가 O(logN)이 되어 탐색, 삽입, 삭제 연산의 수행시간이 O(logN)이 보장된다. |
| 117 | +AVL트리는 4가지 회전 (LL,RR,LR,RL) 을 통해 균형을 잡습니다. |
| 118 | +
|
| 119 | +``` |
| 120 | + |
| 121 | +- 시간복잡도 |
| 122 | + |
| 123 | +| AVL트리 | 평균 | 최악 | |
| 124 | +|-------|---|----| |
| 125 | +| 공간 |O(N)|O(N)|O(logN)| |
| 126 | +| 삽입 |O(logN)|O(logN)| |
| 127 | +| 삭제 |O(logN)|O(logN)| |
| 128 | +| 탐색 |O(logN)|O(logN)| |
| 129 | + |
| 130 | + |
0 commit comments