2023. 8. 26. 14:50ㆍ논자시
퀵 정렬 수도코드
quickSort(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){
x<- A[r];
i<-p-1:
for j<-p to r-1
if (A[j]<=x then A[++i]<->A[j];
A[i+1]<->A[r];
return i+1;
}
퀵 정렬 시간 복잡도
분할은 배열의 왼쪽부터 끝까지 한 번 훑어나가는 작업이기 때문에 O(n) 만큼의 시간이 든다.
퀵 정렬의 수행에서 가장 이상적인 경우는 분할이 항상 반반씩 균등하게 될 때이다.
이 때 시간 복잡도는 T(n) = T(n/2) + O(n)이 된다.
최악의 경우는 계속해서 한쪽은 하나도 없고 다른쪽에 다 몰리도록 분할이 되는 경우이다.
이 때의 시간 복잡도는 T(n) = T(n-1) + O(n)이 된다.
힙정렬
힙은 이진트리로서 맨 아래 층을 제외하고는 완전히 채워져있고 맨 아래층은 왼쪽부터 꽉채워있다
힙은 다음 힙 성질을 만족한다 : 각 노드의 값은 자기 자식의 값보다 작다.
힙을 만드는 함수는 buildHeap, heapify 함수로 동작한다.
heapify(A, k, *) 는 A[k]에 매달린 두 서브 트리가 힙 성질을 만족하는 상태에서 A[k]를 루트로 하는 서브 트리 전체가 힙성질을 만족하도록 수선하는 함수이다. 루트 노드 (A[k] 를 제외한 모든 노드가 힙성질을 만족하고 있다고 가정한다)
리프 노드는 그 자체로 힙성질을 만족하므로 buildHeap()은 리프가 아닌 노드 중 맨 뒤에서부터 루트로 삼아 heapify()를 수행한다.
힙정렬 수도코드 - 빌드
buildHeap(A[], n){
for i<-rounddown(n/2) down to 1
heapify(A, i, n);
}
heapify(A[], k, n){
left<-2k;
right<-2k+1;
if (right<=n) then{
if (A[left]<A[right]) then smaller<-left;
else smaller<-right;
}
else if (right<=n) then smaller<-left;
else return;
if (A[smaller]<A[k]) then {
A[k]<->A[smaller];
heapify(A, smaller, n);
}
}
힙이 완성되었으면 정렬 작업을 한다. 루트 노드에 있는 원소를 제거해 다른 곳에 저장한다. 루트 노드가 없어졌으므로 트리의 크기가 하나 줄었다. 맨 끝에 있는 원소를 루트 노드로 옮겨 새로운 루트로 삼는다. heapify를 이용해 힙성질을 만족하도록 수선을한다.
heapSort(A, n)
{
buildHeap(A, n);
for i<-n downto 2{
A[1]<->A[i]
heapify(A, 1, i-1);
}
}
힙정렬 수행시간
힙 정렬의 수행시간은 buildHeap()은 O(n)의 시간이 든다. 그리고 for 루프는 n-1번 순환하고 각 순환해서 시간을 좌우하는 heapify는 O(logn)이 드니까 수행시간은 O(nlogn)이다.
'논자시' 카테고리의 다른 글
[서울대학교 논자시 준비] 알고리즘 : chapter 10 그래프 : 위상정렬 (0) | 2023.08.26 |
---|---|
[서울대학교 논자시 준비] 알고리즘 : chapter 10 그래프 : dfs, bfs (3) | 2023.08.26 |
[서울대학교 논자시 준비] 알고리즘 : chapter 5 선택 알고리즘 (0) | 2023.08.26 |
[서울대학교 논자시 준비] 알고리즘 : chapter 4 정렬 - 계수정렬 (0) | 2023.08.26 |
[서울대학교 논자시 준비] 알고리즘 : chapter 8 집합의 처리 (0) | 2023.08.17 |