우선순위 큐란?
우선순위 큐는 큐의 한 종류로, 데이터의 삽입 순서와 상관없이 우선순위가 높은 데이터부터 처리하는 구조입니다. 힙은 우선순위 큐를 효율적으로 구현할 수 있는 자료구조입니다.
최소 힙을 이용하면 가장 낮은 우선순위의 데이터를, 최대 힙을 이용하면 가장 높은 우선순위의 데이터를 처리할 수 있는 장점이 있습니다
데이터를 삽입하거나 삭제할 때는 O(log N)의 시간 복잡도를 가집니다. 이는 새로운 데이터를 추가하거나 제거한 후 힙 속성을 유지하기 위해 힙을 재정렬하는 작업이 트리의 깊이에 따라 수행되기 때문입니다.
루트 노드(최솟값 또는 최댓값)를 가져오는 작업은 O(1)의 시간 복잡도를 가집니다. 루트 노드에 최솟값 또는 최댓값이 저장되기 때문입니다.
항상
자식 노드 보다 크거나 같음항상
자식 노드의 보다 작거나 같음class MinHeap {
constructor() {
this.heap = [];
}
insert(value) {
this.heap.push(value);
this.heapifyUp();
}
heapifyUp() {
let index = this.heap.length - 1;
while (index > 0) {
let parentIndex = this.getParentIndex(index);
if (this.heap[parentIndex] > this.heap[index]) {
this.swap(parentIndex, index);
index = parentIndex;
} else {
break;
}
}
}
remove() {
if (this.heap.length === 0) return null;
if (this.heap.length === 1) return this.heap.pop();
const root = this.heap[0];
this.heap[0] = this.heap.pop();
this.heapifyDown();
return root;
}
heapifyDown() {
let index = 0;
while (this.getLeftChildIndex(index) < this.heap.length) {
let smallerChildIndex = this.getLeftChildIndex(index);
let rightChildIndex = this.getRightChildIndex(index);
if (
rightChildIndex < this.heap.length &&
this.heap[rightChildIndex] < this.heap[smallerChildIndex]
) {
smallerChildIndex = rightChildIndex;
}
if (this.heap[index] > this.heap[smallerChildIndex]) {
this.swap(index, smallerChildIndex);
index = smallerChildIndex;
} else {
break;
}
}
}
peek() {
return this.heap[0] || null;
}
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
getParentIndex(i) {
return Math.floor((i - 1) / 2);
}
getLeftChildIndex(i) {
return 2 * i + 1;
}
getRightChildIndex(i) {
return 2 * i + 2;
}
}