완전 이진 트리의 일종으로 우선 순위 큐를 위해 만들어진 구조
최대 값, 최소 값을 쉽게 추출할 수 있다.
7
/ |
5 6
/ | / |
1 2 3 4
이런 모습 (완전 이진 트리)
힙(heap)은 1차원 배열로 쉽게 구현될 수 있다.
정렬해야 할 n개의 요소들을 1차원 배열에 기억한 후 최대 힙 삽입을 통해 차례대로 삽입한다.
최대 힙으로 구성된 배열에서 최댓값부터 삭제한다.
힙에 새로운 요소가 들어오면, 일단 새로운 노드를 힙의 마지막 노드에 이어서 삽입한다.
새로운 노드를 부모 노드들과 교환해서 힙의 성질을 만족시킨다.
public static void heapify(int[] lst, int n, int i) {
int largest = i; // 현재 노드
int left = 2 * i + 1; // 왼쪽 자식
int right = 2 * i + 2; // 오른쪽 자식
// 왼쪽 자식이 더 크면 largest 갱신
if (left < n && lst[left] > lst[largest]) {
largest = left;
}
// 오른쪽 자식이 더 크면 largest 갱신
if (right < n && lst[right] > lst[largest]) {
largest = right;
}
// largest가 변경되었으면 교환 및 재귀적으로 힙화
if (largest != i) {
int temp = lst[i];
lst[i] = lst[largest];
lst[largest] = temp;
// 재귀적으로 하위 트리를 힙화
heapify(lst, n, largest);
}
}
public static void heapSort(int[] lst) {
int n = lst.length;
// 힙 빌드: 최대 힙 생성
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(lst, n, i);
}
// 힙 정렬
for (int i = n - 1; i > 0; i--) {
// 루트(가장 큰 값)를 끝으로 보냄
int temp = lst[0];
lst[0] = lst[i];
lst[i] = temp;
// 나머지 힙화
heapify(lst, i, 0);
}
}