TIL
[클라우딩 어플리케이션 엔지니어링 TIL] - DAY 20
blackmilktea
2024. 5. 13. 19:31
힙(Heap)
최댓값(Max) 또는 최솟값(Min)을 찾아내는 연산을 빠르게 하기 위해 고안된 완전이진트리(Complete binary tree)의 일종이다. 힙에서는 가장 높은(또는 가장 낮은) 우선순위를 가지는 노드가 항상 뿌리 노드에 오게되는 특징이 있어며, 이를 이용해 우선순위 큐(Priority Queue)를 구현할 때 내부적으로 이용하는 자료구조이다.
힙의 종류
- 최대 힙(Max Heap): 모든 노드가 자식 노드보다 작거나 같은 값을 가지는 힙
- 최소 힙(Min Heap): 부모 노드의 값이 자식 노드의 값보다 작거나 같은 값을 가지는 힙
최소 힙(Min Heap) 구현
최소 힙을 구현하는데 필요한 삽입 연산
- 힙의 마지막 노드에 새로은 노드 추가
- 새로운 노드를 추가한 위치에서부터, 부모 노드와 새로 추가된 노드의 값을 비교
- 만약 새로 추가한 노드의 값이 부모 노드보다 작다면, 부모 노드와 새로 추가한 노드 위치 교환
- 이전 단계에서 교환된 노드와 부모 노드의 값을 비교하여 이 단계를 반복
class MinHeap {
constructor() {
this.heap = [null];
}
push(value) {
this.heap.push(value);
let currentIndex = this.heap.length - 1;
let parentIndex = Math.floor(currentIndex / 2);
// 부모 노드가 존재하고 삽입할 값이 부모 노드보다 작은 경우
while (parentIndex !== 0 && this.heap[parentIndex] > value) {
this._swap(parentIndex, currentIndex)
currentIndex = parentIndex;
parentIndex = Math.floor(currentIndex / 2);
}
}
pop() {
if (this.isEmpty()) return; // 힙이 빈 경우
if (this.heap.length === 2) return this.heap.pop(); // 루트 정점만 남은 경우
const returnValue = this.heap[1]; // 반환할 최솟값
this.heap[1] = this.heap.pop(); // 힙의 끝에 있는 값을 루트 노드로 이동
let currentIndex = 1;
let leftIndex = 2;
let rightIndex = 3;
// 루트 노드부터 자식 노드를 비교하면서 작은 값 탐색 후 교환
while (this.heap[currentIndex] > this.heap[leftIndex] ||
this.heap[currentIndex] > this.heap[rightIndex]) {
if (this.heap[leftIndex] > this.heap[rightIndex]) {
this._swap(rightIndex, currentIndex)
currentIndex = rightIndex;
} else {
this._swap(leftIndex, currentIndex)
currentIndex = leftIndex;
}
leftIndex = currentIndex * 2;
rightIndex = currentIndex * 2 + 1;
}
return returnValue;
}
}
_swap(a, b) {
[this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]];
}
isEmpty() {
return this.heap.length === 1;
}
참고
https://ko.wikipedia.org/wiki/%ED%9E%99_(%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0)