
정렬해야 할 배열을 절반씩 나누어(Divide) 각각 정렬한 후 합친다.
MergeSort(A, left, right) {
if (left < right) {
mid = floor((left + right) / 2);
MergeSort(A, left, mid);
MergeSort(A, mid+1, right);
Merge(A, left, mid, right);
}
}
1번 줄의 MergeSort()의 Effort는 이며 4번,5번 줄의 MergeSort()의 Effort는 이다.
Merge()의 Effort는 이다.
그 외의 줄은 constant Effort를 가진다.
이를 점화식(Recurrence)으로 나타내면

풀이과정

점화식을 푸는 방법

힙의 조건
heaps are usually implemented as arrays without information loss
Root node가 인 경우
heap height =>
Heapify(A, i) {
l = Left(i); r = Right(i);
if (l <= heap_size(A) && A[l] > A[i])
//첫 번째 조건:child가 2개보다 적을수도 있어서
largest = l;
else
largest = i;
if (r <= heap_size(A) && A[r] > A[largest])
largest = r;
if (largest != i)
Swap(A, i, largest);
Heapify(A, largest);
}BuildHeap(A) {
heap_size(A) = length(A);
for (i = length[A]/2 downto 1)
//leaf node때문에 절반 건너뛰고 시작
Heapify(A, i);
}Max Heap으로 root노드를 찾은 후 root노드와 최하단의 leaf node를 바꾼다. 바꾼 leaf node는 없는 셈 치고 root node에서 Heapify를 부르는 과정을 반복해 오름차순의 정렬을 얻는 방법.
HeapSort(A) {
BuildHeap(A); //O(n)
for (i = length(A) downto 2) { //O(n)
Swap(A[1], A[i]);
heap_size(A) -= 1;
Heapify(A, 1); //O(logn)
}
}
HeapSort의 시간복잡도는
MergeSort와 HeapSort 비교
데이터의 value가 같을 때 직전의 선후관계를 유지하는 것을 stable하다고 한다. 예로는 excel이 있다.
- in-memory
- 메인 메모리에 모든 데이터가 저장되어 있고 disk를 백업용으로 사용한다.
- memory(RAM)이 disk보다 빠르기 때문에 in-memory 방식이 더 좋다.
- disk-based
- 모든 데이터를 disk에 저장하고 메모리를 caching에 사용한다.
in-place 정렬
- 원소들의 개수에 비해 충분히 무시할 만한 저장공간만을 더 사용하는 정렬 알고리즘
cache friendly
- 캐쉬는 지역성(locality)를 가지는데 이는 데이터에 대한 접근이 시간적, 공간적으로 가깝게 발생하는 것을 말한다. 캐시의 적중률(Hit rate)을 극대화하여 캐시가 효율적으로 동작하기 위해 사용되는 성질이다.
(참고 : https://rebro.kr/180)
- 직접적인 핸들링은 하기 힘들지만 알고리즘이 캐쉬 메모리를 얼마나 유용하게 쓰는가가 성능에 영향을 미친다.
QuickSort(A, p, r) {
if (p < r) {
q = Partition(A, p, r); //q는 pivot value 자리
QuickSort(A, p, q-1);
QuickSort(A, q+1, r);
}
}
Partition(A, l, r) {
p = A[r];
i = l;
j = r - 1;
while (TRUE) {
while A[i] <= p
i++;
while A[j] > p
j--;
if (i < j)
Swap(A, i, j);
else
Swap(A, i, r);
return i;