힙 정렬
자료구조인 힙을 이용하여 정렬을 수행하는 방법입니다. 그렇다면 힙이 무엇일까요?
힙 (Heap)
힙은 완전 이진 트리이며 최소 힙과 최대 힙이 있습니다. 여기서 완전 이진 트리나 힙에 대해서 더 설명하지는 않겠습니다. 힙에 대해서 잘 모르시는 분께서는 공부를하고 다시 보시는 것을 추천드립니다. : )
힙 정렬을 다시 말하자면, 최소 힙이나 최대 힙을 이용하여 정렬하는 방법입니다. 내림차순 정렬을 위해서는 최대 힙을 사용하고, 오름차순 정렬을 위해서는 최소 힙을 사용합니다.
힙 정렬의 과정은 다음과 같습니다. (설명을 위해 내림차순 정렬을 예시로 보여드리겠습니다.)
- 정렬할 데이터들을 최대 힙으로 만듭니다.
- 최대 힙의 루트에 있는 가장 큰 값을 마지막 요소와 교환하여, 힙의 사이즈를 줄입니다.
- 최대 힙을 다시 구성합니다.
- 힙의 사이즈가 1보다 크면 위의 과정을 반복합니다.
1) 최댓값인 루트의 9를 삭제 후, 마지막 노드를 가져옵니다.
2) 루트로 삽입된 노드와 자식 노드와 비교하여 큰 값과 교환합니다.
3) 최대 힙이 아니라면 다시 자식 노드와 비교하여 교환해줍니다. 위의 과정을 반복합니다.
시간 복잡도
완전 이진 트리인 힙의 높이는 $O(logn)$입니다. 데이터 하나를 힙에 삽입, 삭제하는 과정에서 힙을 재구성하는 시간은 $O(logn)$가 소요됩니다. 이에 요소개수 n개를 곱하면 전체 $O(nlogn)$의 시간 복잡도를 가집니다.
자바스크립트 코드
let arrLen;
function swap(arr, i, j){
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function heapify(arr, i){
let max = i;
let left = 2 * i + 1;
let right = 2 * i + 2;
if(left < arrLen && arr[left] > arr[max]){
max = left;
}
if(right < arrLen && arr[right] > arr[max]){
max = right;
}
if(max != i){
swap(arr, i, max);
heapify(arr, max);
}
}
function heapSort(arr){
arrLen = arr.length;
for(let i = Math.floor(arrLen / 2); i >= 0; i--){
heapify(arr, i);
}
for(let i = arrLen - 1; i > 0; i--){
swap(arr, 0, i);
arrLen--;
heapify(arr, 0);
}
return arr;
}
console.log(heapSort([13, 1, 3, 7, 9, 11, 5]));
장점
- 시간 복잡도가 $O(nlogn)$으로 빠른 편에 속합니다.
- 가장 큰 값을 구하거나 가장 작은 값을 구할 때 좋습니다.
단점
- 실제 프로그램에 구현할 경우 평균 계산 속도가 퀵 정렬보다 느리고 불안정합니다.
정리
힙 정렬은 이름에도 힙이 드러가는 만큼 자료구조 힙을 사용하여 정렬을 수행합니다. 이는 힙에 대한 지식이 없으면 이해하기 힘드니 공부하고 오시는 것을 추천드립니다. 만약 힙에 대해 알고있다면, 어려운 내용은 아닐 것입니다. : >
'Algorithm' 카테고리의 다른 글
깊이 우선 탐색 (DFS)과 너비 우선 탐색 (BFS) (0) | 2021.09.17 |
---|---|
이진 탐색 (Binary Search) (0) | 2021.09.17 |
퀵 정렬 (Quick Sort) (0) | 2021.09.13 |
병합 정렬 (Merge Sort) (0) | 2021.09.13 |
삽입 정렬 (Insertion Sort) (0) | 2021.09.13 |
댓글