6. 정렬 - quick, merge
퀵 정렬
- 일반적으로 사용되고 있는 아주 빠른 정렬 알고리즘이다.
- 시간 복잡도는 평균적으로 n log n이지만, 최악의 경우 O(n^2)이다.
원리
- 피벗이라고 부르는 기준이 될 임의의 값을 선택한다.
- 피벗 이하의 그룹, 피벗 이상의 그룹으로 나눈다.
- 두 그룹에서 다시 각각의 피벗을 선정하고 그룹을 쪼갠다.
- 이를 반복하면 정렬된다.
코드
static void quickSort(int[] a, int left, int right) {
int pl = left;
int pr = right;
int x = a[(pl + pr) / 2]; // 피벗
dp {
while (a[pl] < x) pl++;
while (a[pr] > x) pr--;
if (pl <= pr)
swap(a, pl++, pr--);
} while (pl <= pr); // 피벗을 기준으로 그룹이 나뉘면 false가 된다.
if (left < pr) quicksort(a, left, pr);
if (pl < right) quickSort(a, pl, righ);
}
- 코드에서는 피벗을 중간값으로 했지만, 실행 효율을 높일 수 있는 방법이 있다.
- 나눌 배열의 처음, 가운데, 끝 요소를 정렬한 다음 가운데 요소와 끝에서 두번째 요소를 교환한다.
- 세 요소를 선택하고 그 중에서 가운데 요소를 택하면 신뢰도가 더 높다.
- 세 요소는 분류되므로 이들을 빼고 정렬을 수행하면 된다.
병합 정렬
- 배열을 앞부분과 뒷부분으로 나누어 각각 정렬한 다음 병합하는 작업을 반복하여 정렬을 수행하는 알고리즘이다.
- 시간 복잡도는 O(n log n)이며, 안정적이다.
코드
static int[] buff;
buff = new int[n];
static void mergeSort(int[] a, int left, int right) {
if (left < right) {
int i;
int center = (left + right) / 2;
int p = 0;
int j = 0;
int k = left;
mergeSort(a, left, center);
mergeSort(a, center + 1, right);
// a의 왼쪽 그룹을 buffer에 복사
for (i = left; i <= center; i++)
buff[p++] = a[i];
// a의 오른쪽 그룹이 끝나기 전 and buffer가 끝나기 전까지
while (i <= right && j < p)
// 두 그룹을 비교하여 작은 값을 a의 처음부터 삽입
a[k++] = (buff[j] <= a[i]) ? buff[j++] : a[i++];
// buffer의 요소가 남아있는 경우 a에 삽입
while (j < p)
a[k++] = buff[j++];
}
}
buff = null;
Author And Source
이 문제에 관하여(6. 정렬 - quick, merge), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@doforme/6.-정렬-quick-merge저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)