http://academy.hanb.co.kr
쉽게 배우는 알고리즘
3장. 정렬
Sorting IT COOKBOOK IT COOKBOOK3장. 정렬
Sorting
은유, 그것은 정신적 상호연관성의 피륙을
짜는 방법이다.
은유는 살아있다는 것의 바탕이다.
-그레고리 베이트슨
- 3 - 한빛미디어㈜
학습목표
• 기본 정렬 알고리즘을 이해한다.
• 정렬을 귀납적 관점에서 볼 수 있도록 한다.
• 1장과 2장에서 배운 기법을 사용해 각 정렬의
수행시간을 분석할 수 있도록 한다.
• 비교정렬의 한계를 이해하고, 선형시간 정렬이
가능한 조건과 선형시간 정렬 알고리즘을 이해
한다.
IT COOKBOOK IT COOKBOOKSorting Algorithms
• 대부분 O(n
2)과 O(nlogn) 사이
• Input이 특수한 성질을 만족하는 경우에는 O(n)
sorting도 가능
IT COOKBOOK IT COOKBOOK 5
-원시적 Sorting 알고리즘들의 재조명
• 알고리즘을 보는 시각
– flow 중심
– 관계 중심
• 원시적 정렬 알고리즘들을 관계 중심의
시각으로 다시 한 번 조명
– 생각하는 방법에 대한 좋은 연습 자료
IT COOKBOOK IT COOKBOOKSelection Sort
• 각 루프마다
– 최대 원소를 찾는다
– 최대 원소와 맨 오른쪽 원소를 교환한다
– 맨 오른쪽 원소를 제외한다
• 하나의 원소만 남을 때까지 위의 루프를 반복
7
-The largest item
ü 수행시간: (n-1)+(n-2)+···+2+1 = O(n
2)
Worst case
Average case
Finding the Recursive Structure
IT COOKBOOK IT COOKBOOK
selectionSort(A[], n) ▷배열A[1 ... n]을 정렬한다 {
forlast ← n downto2 { --- ① A[1 ... last] 중 가장 큰 수A[k]를 찾는다; --- ② A[k] ↔ A[last]; ▷ A[k]와A[last]의 값을 교환 --- ③ } } ü 수행시간: —①의 for루프는 n-1번 반복 — ②에서 가장 큰 수를 찾기 위한 비교횟수: n-1, n-2, …, 2, 1 — ③의 교환은 상수 시간 작업
ü (n-1)+(n-2)+···+2+1 = O(n
2)
IT COOKBOOK IT COOKBOOK 9 -15 11 29 20 65 3 73 48 31 8 15 11 29 20 65 73 48 31 8 정렬할 배열이 주어짐 가장 큰 수를 찾는다 (73) 73 11 29 20 65 3 15 48 31 8 73을 맨 오른쪽 수(15)와 자리 바꾼다 73 11 29 20 65 3 15 48 31 8 맨 오른쪽 수를 제외한 나머지에서 가장 큰 수를 찾는다 (65) 73 65 29 20 11 3 15 48 31 8 65를 맨 오른쪽 수(11)와 자리 바꾼다 73 65 29 20 11 3 15 48 31 8 맨 오른쪽 두 수를 제외한 나머지에서 가장 큰 수를 찾는다 (48) 73 65 48 31 29 20 15 11 3 8 8을 맨 오른쪽 수(3)와 자리 바꾼다 3 73 65 48 31 29 20 15 11 8 3 최종 배열 . . . 1 의 첫번째 loop 1 의 두번째 loop
Selection Sort의
작동 예
IT COOKBOOK IT COOKBOOKBubble Sort
ü 수행시간: (n-1)+(n-2)+···+2+1 = O(n
2)
Worst case
11 -bubbleSort(A[], n) ▷ A[1 ... n]을 정렬한다 {
forlast ← n downto2 --- ① fori ← 1 tolast-1 --- ② if(A[i] > A[i+1]) thenA[i] ↔ A[i+1]; ▷ 원소 교환 -- ③ } ü 수행시간: —①의 for루프는 n-1번 반복 — ②의for루프는 각각 n-1, n-2, …, 2, 1번 반복 — ③은 상수 시간 작업
ü (n-1)+(n-2)+···+2+1 = O(n
2)
IT COOKBOOK IT COOKBOOK 15 65 29 20 11 8 73 48 31 3 15 65 29 20 11 8 73 48 31 3 정렬할 배열이 주어짐 왼쪽부터 시작해 이웃한 쌍들을 비교해간다 15 65 29 20 11 73 8 48 31 3 순서대로 되어 있지 않으면 자리 바꾼다 73 15 65 29 20 11 8 48 31 3 맨 오른쪽 수(73)를 대상에서 제외한다 15 65 29 20 73 11 8 48 31 3 15 65 29 73 20 11 8 48 31 3 73 15 65 29 20 11 8 48 31 3…
Bubble Sort의 작동 예
IT COOKBOOK IT COOKBOOK 13 -73 15 65 29 20 11 48 8 31 3 순서대로 되어 있지 않은 경우에는 자리 바꾼다 73 15 65 29 20 48 11 8 31 3 73 15 65 29 48 20 11 8 31 3 73 15 65 48 29 20 11 8 31 3 73 15 65 48 29 20 11 8 31 3 73 65 15 48 29 20 11 8 31 3 73 65 15 48 29 20 11 8 31 3 맨 오른쪽 수(65)를 대상에서 제외한다 73 15 65 29 20 11 8 48 31 3 왼쪽부터 시작해 이웃한 쌍들을 비교해간다 IT COOKBOOK IT COOKBOOK 8 3 11 15 20 29 31 48 65 73 앞의 작업을 반복하면서 계속 제외해 나간다 73 65 48 31 29 20 15 11 8 3 두개짜리 배열의 처리를 끝으로 정렬이 완료된다
…
73 65 48 31 29 20 15 11 8 3 ü Improved BubbleSort — 배열이 우연히도 정렬되어 있는 경우에도 의미 없이 순환함 — 개선책 : 교재 76p 참조15
-Insertion Sort
ü 수행시간: O(n
2)
Worst case: 1+2+···+(n-2)+(n-1)Average case: ½ (1+2+···+(n-2)+(n-1)) IT COOKBOOK IT COOKBOOK insertionSort(A[], n) ▷ A[1 ... n]을 정렬한다 { fori ← 2 ton --- ① A[1 ... i]의 적당한 자리에 A[i]를 삽입한다; --- ② } ü 수행시간: —①의for루프는 n-1번 반복 — ②의 삽입은 최악의 경우 i-1회 비교 ü 삽입시간: —A[i]가 A[i-1]보다 크면 그냥 제자리에 두면 됨. 그렇지 않다면, — A[i-1]부터 시작해서 왼쪽으로 차례로 훑으면서 A[i]가 들어갈 자리를 찾는다.
ü Worst case: 1+2+···+(n-2)+(n-1)
= O(n2)
IT COOKBOOK IT COOKBOOK
17
-Inductive Verification of Insertion Sort
• 배열 A[1]만 놓고 보면
– 정렬되어 있음
• 배열 A[1 … k]까지 정렬되어 있다면
è
②행의 삽입에 의해 A[1 … k+1]까지 정렬된다
ü고등학교에서 배운 수학적 귀납법과 다를 바 없음
IT COOKBOOK IT COOKBOOK• 각자 생각해보기
• 삽입정렬과 가장 큰 차이점은 무엇인가?
– 교재 79p 참조
Inductive
Verification
of
Selection/Bubble Sort
19 -mergeSort(A[ ], p, r) ▷ A[p ... r]을 정렬한다 { if(p < r) then { q ← (p+q)/2; --- ① ▷ p, q의 중간 지점 계산 mergeSort(A, p, q); --- ② ▷ 전반부 정렬 mergeSort(A, q+1, r); --- ③ ▷ 후반부 정렬 merge(A, p, q, r); --- ④ ▷ 병합 } } merge(A[ ], p, q, r) { 정렬되어 있는 두 배열 A[p ... q]와 A[q+1 ... r]을 합하여 정렬된 하나의 배열 A[p ... r]을 만든다. }
Mergesort
IT COOKBOOK IT COOKBOOK 31 3 65 73 8 11 20 29 48 15 31 3 65 73 8 11 20 29 48 15 정렬할 배열이 주어짐 배열을 반반으로 나눈다 각각 독립적으로 정렬한다 3 8 31 65 73 11 15 20 29 48 병합한다 (정렬완료) 3 8 11 15 20 29 31 48 65 731
2 3
4
Mergesort의 작동 예
IT COOKBOOK IT COOKBOOK 21 -3 8 31 65 73 11 15 20 29 48 i j t 8 31 65 73 11 15 20 29 48 3 i j t 31 65 73 11 15 20 29 48 3 8 i j t p q r
Merge의 작동 예
IT COOKBOOK IT COOKBOOK 31 65 73 15 20 29 48 3 8 11 i j t 31 65 73 20 29 48 3 8 11 15 i j t 31 65 73 29 48 3 8 11 15 20 i j t23 -31 65 73 48 3 8 11 15 20 29 i j t 65 73 48 3 8 11 15 20 29 31 i j t 65 73 3 8 11 15 20 29 31 48 i j t IT COOKBOOK IT COOKBOOK 3 8 11 15 20 29 31 48 65 73 i j t
IT COOKBOOK IT COOKBOOK 25 -9 | 4 7 2 | 9 4 7 | 2 7 2 9 4½3 8 6 1 7 7 2 2 2 7 2 7 9 4 9 4 4 9 4 9 2 4 7 9 1 3 6 8 2 4 7 91 2 3 4 6 7 8 9
ü 수행시간: O(nlogn)
Animation (Mergesort)
IT COOKBOOK IT COOKBOOKQuicksort
quickSort(A[], p, r) ▷ A[p ... r]을 정렬한다 { if(p < r) then{ q = partition(A, p, r); ▷ 분할 quickSort(A, p, q-1); ▷ 왼쪽 부분배열 정렬 quickSort(A, q+1, r); ▷ 오른쪽 부분배열 정렬 } } partition(A[], p, r) { 배열 A[p ... r]의 원소들을 A[r]을 기준으로 양쪽으로 재배치하고 A[r]이 자리한 위치를return한다; }27 -1 1 5 3 114
9
24529
6
6
8
8
3 2 1 3 1 4 2 2 1 3 4 1 2 1 1 12 44 12 1 2 3 4 1 2 3 4 1 2 3 4 59
6
8
9
6
8
8
6
6
8
6
9
6
8
6
6
8
6
8
6
8
9
6
8
9
12 3 4 56
8
9
ü 평균 수행시간: O(nlogn)
ü 최악의 경우 수행시간: O(n
2)
Animation (Quicksort)
IT COOKBOOK IT COOKBOOK 31 8 48 73 11 3 20 29 65 15 8 11 3 15 31 48 20 29 65 73 정렬할 배열이 주어짐. 첫번째 수를 기준으로 삼는다. 기준보다 작은 수는 기준의 왼쪽에 나머지는 기준의 오른쪽에 오도록 재배치한다 기준(31) 왼쪽과 오른쪽을 각각 독립적으로 정렬한다 (정렬완료) 3 8 11 15 20 29 31 48 65 73(a)
(b)
Quicksort의 작동 예
IT COOKBOOK IT COOKBOOK 29 -31 8 48 73 11 3 20 29 65 15 31 8 48 73 11 3 20 29 65 15 8 31 48 73 11 3 20 29 65 15 8 31 48 73 11 3 20 29 65 15 8 31 48 73 11 3 20 29 65 15 8 11 48 73 31 3 20 29 65 15
p
r
i j i j i j i j i j i j(a)
(b)
(c)
Partition의 예
IT COOKBOOK IT COOKBOOK 8 11 3 73 31 48 20 29 65 15 8 11 3 73 31 48 20 29 65 15 8 11 3 73 31 48 20 29 65 15 8 11 3 73 31 48 20 29 65 15 8 11 3 15 31 48 20 29 65 73 i j i j i j i i(d)
(e)
31
-Heapsort
• Heap(최소힙을 가정)
– Complete binary tree로서 다음의 성질을 만족한다
• 각 노드의 값은 자신의 children의 값보다 작다.(힙에 값이 같은 원소가 두 개 이상 있는 경우에는 “작다” 대신 “작거나 같다”) • 최소힙에서는 이진 트리의 루트에는 최소값이 자리하게 됨.
• Heapsort
– 주어진 배열을 힙으로 만든 다음, – 힙에서 가장 작은 값을 차례로 하나씩 제거하면서 힙 크기를 줄여나감. – 나중에 힙에 아무 원소도 남아 있지 않으면 힙정렬 완료. – 제거 순서가 정렬 순서임 IT COOKBOOK IT COOKBOOK3
6
4
8
9
7
3
8
4
6
9
7
Heap
힙
힙 아님
IT COOKBOOK IT COOKBOOK 33
-3
6
4
8
7
9
힙 아님
IT COOKBOOK IT COOKBOOK3
6
4
8
9
7
1
6
5
4
3
2
3
6
4
8
9
7
A
1 2 3 4 5 6Heap은 Array를 이용해서 표현할 수 있다
ü A[k]의 자식: A[2k]와 A[2k+1]에 있음 ü A[k]의 부모: A[ k/2 ]
35
-힙정렬 알고리즘
heapSort(A[ ], n) { buildHeap(A, n); ▷ 힙 만들기 for i ← n downto 2 { A[1] ↔ A[i]; ▷ 교환한 후heapify(A, 1, i-1); ▷ A[1]이 루트가 되게 힙을 수선
} }
ü 최악의 경우에도 O(nlogn) 시간 소요!
IT COOKBOOK IT COOKBOOK힙 만들기
buildHeap(A[ ], n) // A[1…n]을 힙으로 만든다. { for i ß downto 1 // 말단 노드는 생략해도 되므로 부터 시작. 은 리프가 아닌 노드 heapify(A, i, n); // 들 중 맨 마지막 노드의 인덱스임. } Heapify(A[], k, n) // A[k]를 루트로 하는 트리를 힙성질을 만족하도록 수선한다. // A[k]의 두 자식을 루트로 하는 서브트리는 힙 성질을 만족하고 있다. // n은 최대 인덱스(전체 배열의 크기) { left ß 2k; right ß 2k+1;// 작은 자식 고르기. smaller: A[2k]와 A[2k+1] 중 작은 원소
if (right <= n) then { // k가 두 자식을 가지는 경우
if (A[left] < A[right]) then smaller ß left; else smaller ß right;
}
else if (left <= n) then smaller ß left; // k의 왼쪽 자식만 있는 경우
else return; // A[k]가 말단 노드임. 끝남.
// 재귀적 조정
if (A[smaller] < A[k]) then {
A[k] ßà A[smaller];
heapify(A, smaller, n); }
IT COOKBOOK IT COOKBOOK 37
-3
6
4
8
9
7
7
6
4
8
9
4
6
7
8
9
3
3
3 제거9
6
7
8
4
3
4 제거6
9
7
8
4
3
6
8
7
9
4
3
(a)
(b)
(c)
(f)
(e)
(d)
Heapsort의 작동 예
IT COOKBOOK IT COOKBOOK9
8
7
6
4
3
7
8
9
6
4
3
6 제거9
8
7
6
4
3
7 제거8
9
7
6
4
3
9
8
7
6
4
3
8 제거(g)
(h)
(i)
(j)
(k)
39
-• buildHeap
– Θ(n)
• heapSort
– Θ(nlogn)
힙정렬 알고리즘의 복잡도
ü 최악의 경우에도 O(nlogn) 시간 소요!
IT COOKBOOK IT COOKBOOKO(n) Sort
• 두 원소를 비교하는 것을 기본 연산으로 하는
비교정렬의 하한선은
Θ(nlogn)이다.
• 그러나 원소들이 특수한 성질을 만족하면 O(n)
정렬도 가능
– Counting Sort
• 원소들의 크기가 모두 –O(n) ~ O(n) 범위에 있을 때– Radix Sort
• 원소들이 모두 k 이하의 자리수를 가졌을 때 (k: 상수)IT COOKBOOK IT COOKBOOK 41
-countingSort(A[ ], n)
▷ A[ ]: 입력 배열, B[ ]: 출력 배열, n: 입력 크기
{
for
i ← 1
to
k C[i] ← 0;
for
j ← 1
to
n C[A[j]]++;
▷ 이 지점에서 C[i] : 값이 i인 원소의 총 수for
i ← 2
to
k C[i] ← C[i] + C[i-1]
▷ 이 지점에서 C[i] : i보다 작거나 같은 원소의 총 개수
for
j ← n
downto
1 {
B[C[A[j]]] ← A[j];
C[A[j]]--;
// 같은 값이 여러 개 있을 때
}
}
Counting Sort
IT COOKBOOK IT COOKBOOKradixSort(A[ ], d)
{
for
j = d
downto
1 {
Do a
stable sort
on A[ ] by j
thdigit;
}
}
ü Stable sort
— 같은 값을 가진 item들은 sorting 후에도 원래의 순서가 유지되는 성질을 가진 sort를 일컫는다.Radix Sort
43
-0123
2154
0222
0004
0283
1560
1061
2150
156
0
215
0
106
1
022
2
012
3
028
3
215
4
000
4
00
04
02
22
01
23
21
50
21
54
15
60
10
61
02
83
0
004
1
061
0
123
2
150
2
154
0
222
0
283
1
560
0004
0123
0222
0283
1061
1560
2150
2154
ü Running time: O(n) ← d: a constant
IT COOKBOOK IT COOKBOOK
효율성 비교
Worst Case
Average Case
Selection Sort
n
2n
2Bubble Sort
n
2n
2Insertion Sort
n
2n
2Mergesort
nlogn
nlogn
Quicksort
n
2nlogn
Counting Sort
n
n
Radix Sort
n
n
45
-IT COOKBOOK IT COOKBOOK
한빛미디어㈜