힙은 '최대값 혹은 최소값'을 빠르게 찾기 위한 완전 이진 트리
(이전 글에서 다뤘던 이진 탐색 트리는 '탐색'을 빠르게 하기 위한 구조)
ex) max heap의 경우,
if (new Node > parent Node) swap
조건에 맞지 않을 때까지, root까지 반복.
Heap은 최대 값 혹은 최소 값을 탐색하기 위해 고안된 자료구조로, 최대 값 혹은 최소 값만을 삭제한다. 이는 root Node를 삭제하는 것과 같다.
class Heap {
constructor() {
// index 0에 null을 입력
this.heap = [null];
}
insert(data) {
this.heap.push(data);
let current = this.heap.length - 1;
if (current <= 1) return;
let parent = parseInt(current / 2); // 2로 나눈 몫을 구하면 parent index
while (this.heap[parent] < this.heap[current]) {
this.swap(parent, current); // parent와 current의 값을 swap
current = parent; // current에 parent를 할당
if (current === 1) break; // current 값이 1이면 최상위로 올라온 것이므로 break;
parent = parseInt(current / 2); // 2로 나눈 몫을 구하면 현재 current의 parent index
}
}
swap(a, b) {
[this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]];
}
pop() {
// index 1과 마지막으로 삽입된 index의 값을 swap
this.swap(1, this.heap.length - 1);
// 배열 마지막에 위치한 최대값을 pop
let maxVal = this.heap.pop();
let current = 1;
// 비교해서 큰 값을 위로 올려줌.
// 분기 : 1. No Child, 2. One Child(left), 3. Two Children
while (current <= this.heap.length) {
let left = current * 2;
let right = current * 2 + 1;
// 1. No Child
if (left > this.heap.length) {
break;
} // 2. One Child(left) - 완전 이진 트리 조건에 따라 One Child이면 left만 존재함.
else if (right > this.heap.length) {
// right 값이 존재하지 않을 때
if (this.heap[current] < this.heap[left]) {
// current값 보다 left 값이 더 크면
this.swap(current, left); // current와 left 값을 swap하여 더 큰 값을 위로 올려줌.
current = left;
}
}
// 3. Two Children(left, right)
else {
if (this.heap[left] > this.heap[right]) {
// right보다 left가 더 클 경우
// current와 left를 비교 후 swap
if (this.heap[current] < this.heap[left]) {
this.swap(current, left);
current = left;
}
} else {
// left보다 right이 더 클 경우
// current와 right를 비교 후 swap
if (this.heap[current] < this.heap[right]) {
this.swap(current, right);
current = right;
}
}
}
}
return maxVal;
}
}
const heap = new Heap();
heap.insert(1);
heap.insert(2);
heap.insert(10);
heap.insert(6);
heap.insert(5);
heap.insert(9);
heap.insert(11);
heap.insert(3);
console.log(heap.pop()); // 11
console.log(heap); // [null, 10, 6, 9, 3, 5, 2, 1]
댓글 환영
질문 환영
by.protect-me