정리가 안된 책장에서 원하는 책을 찾는 방법에는 뭐가 있을까?

순서대로 하나씩 찾는 탐색 알고리즘이다. O(n) 시간 복잡도가 걸린다.
나이 맞추기 게임 : Up & Down으로 기준점을 정하여 찾는다.
출처: 이선협 강사님 데브코스 강의 자료
정렬되어 있는 요소들을 반씩 제외하면서 찾는 알고리즘이다. O(log n)만큼 시간복잡도가 걸린다.

하지만 이 방법은 중간에 요소를 추가하거나 삭제하려고 할 경우 선형 시간 복잡도가 소요되는 단점이 존재한다.
이를 해결하기 위해 이진 탐색 트리를 활용한다.
이진 탐색을 위한 이진 트리로써 왼쪽 서브 트리는 루트보다 작은 값이 모여있고 오른쪽 서브 트리는 루트보다 큰 값이 모여있다.

루트에서부터 비교 노드보다 작으면 왼쪽 서브 트리로 크면 오른쪽 서브 트리로 추가해나간다. 값이 같을 경우에는 임의로 왼쪽, 오른쪽 중 하나를 정해서 추가한다.
별다른 처리 없이 부모 정점과의 연결을 끊는다.

제거되는 정점의 부모 간선을 자식 정점을 가르키게 바꾼다.

왼쪽 서브 트리의 가장 큰 값 혹은 오른쪽 서브 트리의 가장 작은 값과 교체하면 된다.
이 경우 교체된 정점의 좌우 자식이 없다면 제거되는 정점의 링크로 대체된다.

const array = [1, 2, 5, 6, 39, 414, 1515];
function binarySearch(array, findValue) {
// left, right, mid 생성
let left = 0;
let right = array.length - 1;
let mid = Math.floor((left + right) / 2);
// 이진 탐색 시작 (left가 right랑 같거나 클때까지)
while (left <= right) {
// mid 값과 같으면 종료
if (array[mid] === findValue) {
return mid;
}
// mid 값이 목표값보다 작으면
if (array[mid] < findValue) {
left = mid + 1; // left를 mid 바로 오른쪽으로 이동
} else {
// mid 값이 목표값보다 크면
right = mid - 1;
}
// mid 재설정
mid = Math.floor((left + right) / 2);
}
return -1; // 찾지 못하면 -1
}
console.log(binarySearch(array, 414));
console.log(binarySearch(array, 1));
console.log(binarySearch(array, 7));
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
// 추가 : 노드 생성 및 루트가 비었으면 추가한 노드가 루트가 됨
insert(value) {
const newNode = new Node(value);
if (this.root === null) {
this.root = newNode;
return;
}
let currentNode = this.root;
while (currentNode !== null) {
// 추가할 값이 현재 노드의 값보다 크면
// 오른쪽 노드의 값보다 추가할 노드의 값이 더 크면
if (currentNode.value < value) {
// 오른쪽 노드의 값이 null이면
if (currentNode.right === null) {
currentNode.right = newNode; // 바로 삽입
break;
}
// 아니면 그대로 이동
currentNode = currentNode.right;
} else {
// 추가할 값이 현재 노드의 값보다 작으면
// 왼쪽 노드의 값보다 추가할 노드의 값이 더 크면
// 왼쪽 노드의 값이 null이면
if (currentNode.left === null) {
currentNode.left = newNode; // 바로 삽입
break;
}
currentNode = currentNode.left; // 그대로 이동
}
}
}
// 찾기
has(value) {
let currentNode = this.root;
while (currentNode !== null) {
if (currentNode.value === value) {
return true;
}
if (currentNode.value < value) {
currentNode = currentNode.right;
} else {
currentNode = currentNode.left;
}
}
return false;
}
}
const tree = new BinarySearchTree();
tree.insert(5);
tree.insert(4);
tree.insert(7);
tree.insert(8);
tree.insert(5);
tree.insert(6);
tree.insert(2);
console.log(tree.has(8));
console.log(tree.has(1));
과제
- 이진 탐색 트리의 요소 제거 부분을 작성해보자.
😅 해당 내용은 공부하면서 정리한 글입니다. 틀린 부분이나 오해하고 있는 부분이 있다면 피드백 부탁드립니다.