develop/Sprint
[알고리즘 자료구조] JavaScript in Heap
온몸비틀기
2024. 5. 1. 23:49
1-1. 힙(Heap)
- 힙은 데이터에서 최대값과 최솟값을 빠르게 찾기 위해 고안된 완전 이진트리(Complete Binary Tree)이다.
- max - heap과 min - heap 두 가지 타입이 있다.
- 최댓값이 맨 위인 힙을 max - heap, 최솟값이 맨 위인 힙을 min - heap 이라고 한다.
- BST(이진 탐색 트리)와 다르다 => 좌, 우 자식의 대소 관계를 반영하지 않는다 => 층(Level)으로 대소 관계를 구분한다
1-2. 힙(Heap) 규칙
- 큐에는FIFO, 스택은 FILO의 규칙이 있듯 힙(Heap)에도 규칙이 있다.
- Heap Rule: 힙은 항상 큰 값이 상위 레벨에 있고 작은 값이 하위 레벨에 있어야 한다.
따라서, 원소를 추가하거나 삭제할때도 위의 규칙이 지켜져야 한다.
![]()
1-3. 배열로 나타낸 힙(Heap)
구현하기 전에 알아야 할 부분이 있다면, 힙(Heap)은 트리를 배열로 나타낼 수 있다는 것이다.
위 이미지에서 Min Heap은 [10, 15, 30, 40, 50, 100, 40], Max Heap = [100, 40, 50, 10, 15, 50, 40 ] 이 된다.
배열로 인해 부모노드, 왼쪽, 오른쪽 자식 노드를 표현할 수 있다.
Min Heap에서 6번째 index를 예로 들어보자.
현재 노드 Index = 6
부모 노드 : Math.floor((자식 노드 Index -1) / 2 ) = 2
왼쪽 자식 노드 Index = (부모노드 * 2) + 1 = 5
오른쪽 자식 노드 Index = (부모노드 * 2) + 2 = 6
| 구분 | 부모노드 | 왼쪽 자식 노드 | 현재노드, 오른쪽 자식 노드 | ||||
|---|---|---|---|---|---|---|---|
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| Node | 10 | 15 | 30 | 40 | 50 | 100 | 40 |
따라서 나중에 구현할 때 기본으로 부모, 자식(오른쪽, 왼쪽) 노드들을 아래와 같이 세팅해주게 된다.
이렇게 배열로 나타냄으로서 아래의 표현이 성립하게 된다.
// 기본 셋팅
// 부모 노드 Index
getParentIndex(i) {
return Math.floor(i - 1 / 2);
}
// 자식 왼쪽 노드 Index
getLeftChildIndex(i) {
return i * 2 + 1;
}
// 자식 오른쪽 노드 Index
getRightChildIndex(i) {
return i * 2 + 2;
}
2. 과정 (max-heap 기준)
힙에는 요소를 삽입할 때와 추출(삭제)할 때 이 두 가지의 구현 방식을 알고 있어야 한다. 설명과 구현은 max-heap을 기준으로 하겠다.
구현하면서 사용했던 주요 함수도 미리 적었다.
2-1. 삽입 알고리즘
- 원소를 맨 마지막에 넣는다. - push()
- 부모의 노드와 비교해 더 크다면 자리를 바꾼다. - swap()
- 현재 노드가 부모 노드보다 작거나 가장 위에 도달하지 않을 때까지 2. 의 과정을 반복한다. - heapifyUp()
2-2. 추출 알고리즘
- 배열의 최상위 노드를 꺼내준다. - maxValue
- 루트노드와 맨 끝에 있는 원소를 교체한다. - this.data[0] = this.data [this.data.length - 1];
- 맨 뒤에있는 원소를 (원래 루트 노드)를 삭제한다. > 배열 크기 줄어듦 - this.data.length--;
- 변경된 노드와 자식 노드들을 비교한다. left, rigth index로 두 자식 간 노드의 크기를 비교하며 루트 노드보다 더 클 경우 자리를 바꿔준다. - heapifyUp(), swap()
- 자식 노드 둘 보다 부모노드가 크거나 가장 바닥에 도달하지 않을 때까지 3. 과정을 반복한다. - heapifyUp()
- 2에서 제거한 원래 루트 노드를 반환한다. - poll() , return maxValue;
3. 힙 (Heap) 사용 사례
여러 개의 값들 중에서 최댓값이나 최솟값을 빠르게 찾아내도록 만들어진 자료구조이다.
- 우선순위 큐를 구현하는데 사용한다.
- 게임엔진에서 각 액터의 우선순위를 정한다.
- 서버에서 많은 트래픽을 처리할 때 우선 처리해야 할 트래픽을 정한다.
- 시뮬레이션 시스템
- 네트워크 트래픽 제어
- 운영 체제에서의 작업 스케쥴링 (우선 순위가 높은 일을 바로 조회할 수 있다.)
- 수치 해석적인 계산