What
pivot(기준점) 기반으로 정렬하는 알고리즘이다.
시간복잡도는? O(n^2)
평균적으로 O(n log n)이지만 오름차순 기준으로 정렬할 때, 9 8 7 6 …. 1이런경우 n^2으로 최악의 시간복잡도를 갖는다.
동작원리
전반적 코드 흐름
- 피봇 기준 정렬
- 구간 나누기(왼쪽,오른쪽) 다시 1번으로
구체적인 정렬 원리
- Pivot 기준 왼쪽 구간에는 pivot 값보다 큰 값을 찾는다
- Pivot 기준 오른쪽 구간에는 pivot 값보다 작은 값을 찾는다
- 왼쪽구간과 오른쪽 구간이 겹치지 않으면 왼쪽 오른쪽 값을 맞바꾼다!
왜 이렇게 정렬할까?
피봇을 기준으로 큰 값을 오른쪽에 놓는다라는 의미이고 정렬을 위해 우선 구간을 살피면서 정확한 위치는 아니지만 나보다 큰놈은 오른쪽에 가는 것이 맞고 나보다 작은 값은 나보다 왼쪽에 있는게 맞다이므로 우선 정확한 위치는 아니지만 대강 놓는다라고 이해하면 될 것 같다.
How
피봇은 여러가지 3가지 경우 선택지가 있다.
- 피봇의 기준이 왼쪽 또는 오른쪽인 경우는 pivot위치에 있는 값이 적절한 위치로 들어간다.
- 가장 왼쪽

- 가장 오른쪽

- 중앙

Why
- Java를 쓰게 되면 Arrays.sort, Collections.sort 라는 메소드의 동작원리의 기반이 되는 정렬(dual-pivot quick sort, 혹은 TimSort(mergeSort + quickSort) )이다. 사용하는데 모르고 있어도 크게 상관 없지만 이처럼 라이브러리를 사용하면서 원리를 안다는 것은 좋은 습관이기 때문이다.
Code
import java.util.Arrays; import java.util.Scanner; import java.util.StringTokenizer; public class QuickSort { static Scanner sc = new Scanner(System.in); public static void main(String[] args) { int n = Integer.parseInt(sc.nextLine()); int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = Integer.parseInt(sc.nextLine()); } // quickSortByMiddlePivot(0, arr.length - 1, arr); quickSortByFirstPivot(0, arr.length - 1, arr); // quickSortByRightPivot(0, arr.length - 1, arr); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } public static void quickSortByRightPivot(int s, int e, int[] arr) { if (s >= e) return; int pivotIndex = e; int l = s; int r = e - 1; while (l <= r) { while (l < e && arr[l] < arr[pivotIndex]) { l++; } while (r >= s && arr[r] > arr[pivotIndex]) { r--; } if (l < r) { swap(arr, l, r); } else { swap(arr, l, pivotIndex); } } quickSortByRightPivot(s, l - 1, arr); quickSortByRightPivot(l + 1, e, arr); } public static void quickSortByFirstPivot(int s, int e, int[] arr) { if (s >= e) return; int pivotIdx = s; int l = s + 1; int r = e; while (l <= r) { while (l <= e && arr[l] < arr[pivotIdx]) { l++; } while (r > s && arr[r] > arr[pivotIdx]) { r--; } if (l < r) { swap(arr, l, r); } else { swap(arr, r, pivotIdx); } } quickSortByFirstPivot(s, r - 1, arr); quickSortByFirstPivot(r + 1, e, arr); } public static void quickSortByMiddlePivot(int s, int e, int[] arr) { if (s >= e) { return; } int pivot = arr[(s + e) >> 1]; int l = s; int r = e; while (l <= r) { while (arr[l] < pivot) { l++; } while (arr[r] > pivot) { r--; } if (l <= r) { swap(arr, l, r); l++; r--; } } quickSortByMiddlePivot(s, l - 1, arr); quickSortByMiddlePivot(l, e, arr); } static void swap(int[] arr, int a, int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } }