[java] 힙 정렬 알고리즘

힙 정렬(Heap Sort)은 힙(Heap) 자료구조를 사용하여 정렬을 수행하는 알고리즘입니다. 이는 선택 정렬(Selection Sort)의 향상된 버전으로 볼 수 있습니다. 이번 포스팅에서는 자바를 사용하여 힙 정렬을 구현하는 방법을 살펴보겠습니다.

힙 정렬 알고리즘 개요

  1. 먼저 주어진 배열을 최대 힙(max heap)으로 만듭니다. 이때, 최대 힙은 부모 노드가 자식 노드보다 항상 큰 값을 가지는 이진트리입니다.
  2. 최대 힙에서는 가장 큰 값을 가지는 요소가 항상 루트 노드에 위치하게 됩니다.
  3. 루트 노드와 마지막 노드를 교환하고, 마지막 노드를 힙에서 제외시킨 후, 다시 최대 힙을 구성합니다.
  4. 위의 과정을 반복하여 정렬을 완성합니다.

자바로 힙 정렬 구현하기

다음은 자바 코드로 구현한 힙 정렬 알고리즘의 예시입니다.

public class HeapSort {
    public void sort(int arr[]) {
        int n = arr.length;

        // 최대 힙을 구성
        for (int i = n / 2 - 1; i >= 0; i--)
            heapify(arr, n, i);

        // 요소를 하나씩 힙에서 추출하여 정렬
        for (int i = n - 1; i > 0; i--) {
            // 최대 요소(루트 노드)를 마지막 노드와 교환
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;

            // 제외된 요소를 대상으로 최대 힙을 다시 구성
            heapify(arr, i, 0);
        }
    }

    void heapify(int arr[], int n, int i) {
        int largest = i; // 루트 노드
        int l = 2 * i + 1; // 왼쪽 자식 노드
        int r = 2 * i + 2; // 오른쪽 자식 노드

        // 왼쪽 자식이 루트보다 크면 largest를 갱신
        if (l < n && arr[l] > arr[largest])
            largest = l;

        // 오른쪽 자식이 루트보다 크면 largest를 갱신
        if (r < n && arr[r] > arr[largest])
            largest = r;

        // largest가 루트가 아니라면 교환이 필요
        if (largest != i) {
            int swap = arr[i];
            arr[i] = arr[largest];
            arr[largest] = swap;

            // 교환이 일어났으므로 자식 노드 확인 필요
            heapify(arr, n, largest);
        }
    }

    public static void main(String args[]) {
        int arr[] = {12, 11, 13, 5, 6, 7};
        int n = arr.length;

        HeapSort heapSort = new HeapSort();
        heapSort.sort(arr);

        System.out.println("정렬된 배열:");
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}

이 코드를 실행하면, 입력된 배열이 힙 정렬 알고리즘에 의해 정렬된 결과를 출력할 것입니다.

힙 정렬은 시간 복잡도가 O(nlogn)으로, 안정적인 정렬 알고리즘 중 하나입니다. 이 알고리즘은 특히 정확한 결과가 필요할 때 유용하게 사용됩니다.

이상으로 자바로 힙 정렬을 구현하는 방법에 대해 알아보았습니다.