힙 정렬(Heap Sort)은 완전 이진 트리를 기반으로 하는 힙(Heap) 자료구조를 활용한 정렬 알고리즘이다. 주로 최대값 또는 최소값을 빠르게 찾아야 하는 문제에서 유용하게 활용된다. 힙 정렬은 불안정 정렬(Unstable Sort)이며, 평균, 최선, 최악의 시간 복잡도는 O(n log n)이다.
아래 그림은 초기 배열에서 최대 힙이 구성되는 과정을 시각적으로 보여준다.
최대값 추출 및 정렬
루트 노드(최대값)를 마지막 요소와 교환하고, 힙 크기를 줄인 뒤 다시 힙을 구성한다.
반복 처리
힙 크기가 1이 될 때까지 위 과정을 반복하며 정렬을 완료한다.
public class HeapSort {
public static void main(String[] args) {
int[] array = {230, 10, 60, 550, 40, 220, 20};
heapSort(array);
for (int value : array) {
System.out.print(value + " ");
}
}
// 힙 정렬 메서드
public static void heapSort(int[] array) {
int n = array.length;
// 초기 힙 구성
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(array, n, i);
}
// 힙에서 최대값 추출 후 정렬
for (int i = n - 1; i > 0; i--) {
swap(array, 0, i); // 최대값을 마지막으로 이동
heapify(array, i, 0); // 힙 재구성
}
}
// 힙 구성 메서드
public static void heapify(int[] array, int n, int i) {
int parent = i; // 부모 노드 인덱스
int left = 2 * i + 1; // 왼쪽 자식
int right = 2 * i + 2; // 오른쪽 자식
// 왼쪽 자식이 더 크다면 부모와 교체
if (left < n && array[parent] < array[left]) {
parent = left;
}
// 오른쪽 자식이 더 크다면 부모와 교체
if (right < n && array[parent] < array[right]) {
parent = right;
}
// 부모 노드가 자식 노드보다 작다면 스왑 후 재귀 호출
if (i != parent) {
swap(array, i, parent);
heapify(array, n, parent);
}
}
// 배열 요소 교환 메서드
public static void swap(int[] array, int a, int b) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
}
장점
단점
최대값/최소값 찾기
k-인근 요소 정렬
힙 정렬은 힙 자료구조의 개념을 기반으로 효율적인 정렬을 제공하지만, 구현의 복잡성으로 인해 다른 정렬 알고리즘에 비해 실무 활용 빈도는 낮다. 그러나 힙 자료구조가 다양한 문제 해결에 활용되는 만큼, 이를 이해하는 과정에서 힙 정렬은 매우 중요한 개념이다. 특히, 대용량 데이터의 특정 연산을 빠르게 처리해야 하는 상황에서 유용하다.