정렬알고리즘2부 - 퀵,합병,히프 정렬
돌딤
2018. 7. 26. 22:27
퀵 정렬
퀵 정렬 의 기본 개념은 기준이 되는 숫자 피벗을 정한 후에 그 숫자를 기준으로 작은 데이터와 큰 데이터를 나누고 다시
분리한 양쪽의 데이터에서 다시 기준이 되는 숫자를 정한 후 그숫자를 기준으로 작은 데이터와 큰 데이터를 나누는 작업을
반복하는 것입니다.. 이러한 작업을 위해선 기준이 되는 값보다 작은 값을 찾기 위한 인덱스와 큰 값을 찾기 위한
인덱스가 필요합니다..
작은 값을 찾기 위한 인덱스는 왼쪽에서 진행하고 큰 값을 찾기 위한 인덱스는 오른쪽부터 진행합니다.
왼쪽에서 진행하는 인덱스는 기준값보다 크거나 같은 경우에 멈추고 오른쪽에서 진행하는 인덱스는 기준값보다 작거나 같은
경우에 멈춥니다. 그 상태에서 해당 인덱스에 위치한 데이터의 위치를 서로 바꿉니다.
이 작업을 반복하면 기준값을 기준으로 좌측에는 작거나 같은 값, 우측에는 크거나 같은 값이 위치하게 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 1 Quick Sort Algorithm 2 3 Partition // ‘분할’의 뜻을 가지고 있다. 4 { 5 low = left + 1 // low의 위치는 left보다 한 칸 오른쪽이다. 6 high = right // high의 위치는 right와 동일하다. 7 pivot = arr[left] // 피벗의 위치는 가장 왼쪽이다. 8 9 while (low <= high) // low와 high가 교차되지 않을 때까지 계속 반복한다. 10 { 11 while (pivot >= arr[low] and low <= right) // 피벗보다 큰 값을 찾을 때까지 12 low++ // low를 한 칸 오른쪽으로 이동한다. 13 14 while (pivot <= arr[high] and high >= (left + 1) // 피벗보다 작은 값을 찾을 때까지 15 high-- // high를 한 칸 왼쪽으로 이동한다. 16 17 18 if (low <= high) // low와 high가 교차되지 않았다면, 19 low가 가리키는 값과 high가 가리키는 값 교환 20 } 21 피벗의 값과 high가 가리키는 값 교환 // low와 high가 교차되었다면 22 return high // high의 위치를 가져온다. 23 } 퀵 정렬 알고리즘 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <stdio.h> #define max 10 int a[11] = { 10, 14, 19, 26, 27, 31, 33, 35, 42, 44, 0 }; int b[10]; void merging(int low, int mid, int high) { int l1, l2, i; for(l1 = low, l2 = mid + 1, i = low; l1 <= mid && l2 <= high; i++) { if(a[l1] <= a[l2]) b[i] = a[l1++]; else b[i] = a[l2++]; } while(l1 <= mid) b[i++] = a[l1++]; while(l2 <= high) b[i++] = a[l2++]; for(i = low; i <= high; i++) a[i] = b[i]; } void sort(int low, int high) { int mid; if(low < high) { mid = (low + high) / 2; sort(low, mid); sort(mid+1, high); merging(low, mid, high); } else { return; } } int main() { int i; printf("List before sorting\n"); for(i = 0; i <= max; i++) printf("%d ", a[i]); sort(0, max); printf("\nList after sorting\n"); for(i = 0; i <= max; i++) printf("%d ", a[i]); } 합병 정렬 알고리즘 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | void downheap(int cur, int k) { int left, right, p; while(cur < k) { left = cur * 2 + 1; right = cur * 2 + 2;and t if (left >= k && right >= k) break; p = cur; if (left < k && data[p] < data[left]) { p = left; } if (right < k && data[p] < data[right]) { p = right; } if (p == cur) break; swap(&data[cur],&data[p]); cur=p; } } void heapify(int n) { int i,p; for(i = (n-1)/2; i >= 0; i--){ downheap(i,n); } //for(i=0;i<size;++i)printf("%d ",data[i]); //printf("\n"); } void heap() { int k; heapify(size); for(k = size-1; k > 0; ){ swap(&data[0],&data[k]); //k--; downheap(0,k); k--; } } 히프 정렬 알고리즘 | cs |
히프 정렬은 maxheap를 만들어서 deletemax를 반복 수행하여 정렬하므로 n을 입력 파일의 크기라 하면 buildheap O(n), n번
deletemax O(nlogn)의 성능을 갖고 있으며, buildheap는 내부 노드에서만 수행합니다. 그리고 단말 노드는 더이상 내려갈 곳
이 없으므로 적용할 필요가 없습니다.
이론적으로는 이상적인 O(nlogn)이나 실제 수행시간이 깁니다. 그러나 뛰어난 성능을 가지면서도 추가적인 메모리가
필요하지 않아 많이 사용합니다.
'노트정리 > 자료구조' 카테고리의 다른 글
[그래프 알고리즘] 깊이 우선 탐색(DFS) 와 너비 우선 탐색(BFS) (0) | 2018.08.01 |
---|---|
정렬 알고리즘 3부 - 계수,기수,버킷 정렬 (0) | 2018.07.26 |
정렬 알고리즘 1부 - 선택,버블,삽입, 쉘 정렬 (0) | 2018.07.25 |
[자료구조] 그래프에 대해 (0) | 2018.07.24 |
[자료구조] 큐와 스택 (0) | 2018.07.24 |