힙(Heap) 자료구조를 기반으로 한 정렬방식
- 정렬해야 할 n개의 요소를 최대 또는 최소 힙을 구성한다. (완전 이진 트리 형태)
- 현재 힙의 root에는 최대 or 최소값. 루트의 값을 마지막 요소(말단 노드)와 바꾼 후에, 힙의 사이즈를 하나 줄인다.
=> 최대 혹은 최소값을 하나 뽑을 수 있다.- 힙의 사이즈가 1보다 크면 이 과정을 반복
힙 Heap
힙 조건을 만족한는 완전 이진 트리(Complete Binary Tree)형태의 자료구조로 우선순위 큐를 위해 만들어졌다.완전 이진 트리 Complete Binary Tree
각 노드의 자식 수가 2 이하인 트리(이진 트리)로, 마지막 레벨은 노드가 왼쪽에 몰려있고 마지막 레벨을 제외하면 모든 단말 노드의 깊이가 같다.힙 조건
- 노드의 키 값은 자식 노드의 키 값보다 항상 크다 (최대힙 Max Heap)
- 노드의 키 값은 자식 노드의 키 값보다 항상 작다 (최소힙 Min Heap)
=> 주어진 데이터를 힙 조건을 만족하게 만드는 것을 Heapify라 함
i/2
i*2
i*2+1
#include <iostream>
using namespace std;
int n, heap[10000001];
void heapify(int i)
{
int cur = 2 * i;
if(cur < n && heap[cur] < heap[cur+1]) cur++;
if(heap[i] < heap[cur])
{
swap(heap[i],heap[cur]);
if(cur <= n/2) heapify(cur);
}
}
void heapsort(int i)
{
swap(heap[1],heap[i]);
int root = 1;
int cur = 2;
while(cur/2<i)
{
cur = 2*root;
if(cur < i-1 && heap[cur] < heap[cur+1]) cur++;
if(cur < i && heap[root] < heap[cur])
swap(heap[root],heap[cur]);
root = cur;
}
}
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&heap[i]);
for(int i = n/2; i > 0; i--) // 최초 heap 생성
heapify(i);
for(int i = n; i > 0; i--) // heap 정렬
heapsort(i);
for(int j = 1; j <= n; j++) // 출력
printf("%d ",heap[j]);
}
시간복잡도
시간복잡도 | |
---|---|
최선 | Ω(nlogn) |
평균 | Θ(nlogn) |
최악 | O(nlogn) |
힙 트리의 전체 높이가 거의 log₂n
(완전 이진 트리이므로)이므로 하나의 요소를 힙에 삽입하거나 삭제할 때 힙을 재정비하는 시간이 log₂n
만큼 소요된다.
요소의 개수가 n
개 이므로 전체적으로 O(nlog₂n)
의 시간이 걸린다.
T(n) = O(nlog₂n)
공간복잡도: O(1)