-
7. 힙 정렬(Heap Sort)Algorithm 2019. 10. 16. 16:29
#힙이란?
힙은 다음 두가지 성질을 가지는 이진트리이다.
1. 구조적 성질: 완전이진트리
2. 힙의 성질: 최대힙 or 최소힙
*완전이진트리
-마지막 레벨을 제외하고 모든 레벨이 가득 차 있는 상태
-마지막 레벨에서 노드는 왼쪽부터 차례로 채워져야 한다.
*Max Heap & Min Heap
-최대힙: 모든 노드 x에 대하여, 그 x의 값은 자신의 자식 노드의 값보다 크거나 같아야 한다.
-최소힙: 모든 노드 x에 대하여, 그 x의 값은 자신의 자식 노드의 값보다 작거나 같아야 한다.
-최대힙에서 최댓값을 찾는 시간과 최소힙에서 최솟값을 찾는 시간은 O(1)로 상수 시간을 가진다. 그 값은 root에 있기 때문이다. 하지만 최대힙에서 최솟값을 찾거나 최소힙에서 최대값을 찾는 것은 노드를 탐색하는 과정이 필요하므로 트리의 높이 만큼의 시간이 걸린다. O(h) = O(log n)
max heap *힙에서 n개의 노드가 있을 때,
- height: log n 내림
- number of leaves: n/2 올림
*힙의 구현
배열로 구현한다.
#힙 정렬 알고리즘(최대힙 이용)
1. 배열(L)을 최대힙으로 만든다.
-rebuildHeap을 이용
2. 최대힙을 정렬된 배열로 만든다.
-힙의 루트에 있는 원소(L[0], 최대 원소)와 마지막 원소(L[last])를 교환한다.
-힙의 크기를 1 줄이고, 루트가 L[0]인 semiheap에 대하여 rebuildHeap을 이용해 힙으로 만든다.
3. last=0이 될때까지 위의 단계 1-2를 반복한다.
//rebuildHeap이란 root의 left subtree와 right subtree가 heap일 때, root까지 포함하여 heap을 만드는 알고리즘
//rebuildHeap using Max heap void rebuildHeap(int* a, int root, int n){ int x = a[root]; int current = root; while(2*current+1 < n){ int left_child = 2*current+1; int right_child = left_child+1; int larger_child; //left_child와 right_child 중 더 큰 값 찾기 if(right_child<n && (a[right_child]<a[left_child])) larger_child=left_child; else larger_child=right_child; //root와 비교해서 heap 만들기 if(x<larger_child){ a[current] = a[larger_child]; current = larger_child; } else break; } a[current]=x; }
void heapsort(int* a, int n){ //step1: 배열 a를 heap(maxheap)으로 만드는 과정 for(int root=(n-1)/2; root>=0; root--){ rebuildHeap(a, root, n); } //step2: 최대힙을 정렬된 배열로 만드는 과정 int heap_size=n; for(int last=n-1; last>0; last--){ int tmp = a[0]; a[0] = a[last]; a[last] = tmp; heap_size--; rebuildHeap(a,0,heap_size); } }
#수행시간 분석
*step 1의 수행시간
-rebuildHeap의 수행시간: O(h) //h = log n
-rebuildHeap (n/2번(내림)) 호출
=> O(n log n)
그러나 이것은 tight한 분석이 아니다. tight한 분석에 따르면 step1의 수행시간은 O(n)
*step 2의 수행시간
-rebuildHeap의 수행시간: O(log n)
-rebuildHeap (n-1)번 호출
=> O(n log n)
따라서, heapsort의 수행시간은 O(n log n)이다.
'Algorithm' 카테고리의 다른 글
9. 정렬 알고리즘 정리 (0) 2019.10.16 6. 분할과 정복_퀵정렬(Quick Sort) (0) 2019.10.04 5. 분할과 정복_병합정렬(Merge Sort) (0) 2019.10.04 4. 삽입 정렬(Insertion Sort) (0) 2019.10.04 3. 버블 정렬(Bubble Sort) (0) 2019.10.04