버블, 선택, 삽입, 병합, 퀵 정렬 등이 있는데 이 중에서 가장 빠른 정렬이 퀵정렬이다. 시간복잡도가 O(NlogN)이다. 속도가 log로 나온다면 연산해야 할 횟수가 절반 혹은 1/n으로 줄어든다는 뜻이다. 가장 느릴때는 O(N^2)이 나오기도 하지만 매번 한개의 원소와 나머지 원소로 나누어지는 경우는 많지는 않으므로 보통 O(NlogN)이 나온다.
https://upload.wikimedia.org/wikipedia/commons/f/fe/Quicksort.gif
퀵 정렬은 분할 정복(divide and conquer) 방법을 통해 리스트를 정렬한다.
재귀 호출이 한번 진행될 때마다 최소한 하나의 원소는 최종적으로 위치가 정해지므로, 이 알고리즘은 반드시 끝난다는 것을 보장할 수 있다.
public List<Integer> quickSortList(List<Integer> arr){
if(arr.size() <= 1){
return arr;
}
//1. 기준값 뽑는 로직 구현
int mid = arr.size()/2;
int pivot = arr.get(mid);
//2. 기준값 기준으로 왼쪽 오른쪽으로 나누어 담는 로직 구현
List<Integer> left = new ArrayList<>();
List<Integer> right = new ArrayList<>();
for (int i = 0; i < arr.size(); i++) {
if(i != mid){
if(arr.get(i) < pivot){
left.add(arr.get(i));
} else{
right.add(arr.get(i));
}
}
}
left = quickSortList(left);
right = quickSortList(right);
List<Integer> result = new ArrayList<>();
result.addAll(left);
result.add(pivot);
result.addAll(right);
return result;
}
public int[] QuickSort (int[] arr, int start, int end){
if(start >= end){
return arr;
}
int pivot = (start+end)/2;
int left = start;
int right = end;
while(left <= right){
while(arr[left] < arr[pivot]){left++;}
while(arr[right] > arr[pivot]){right--;}
if(left <= right){
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
right--;
left++;
}
}
QuickSort2(arr, start, right);
QuickSort2(arr, left, end);
return arr;
}
public void quickSort(int[] arr, int left, int right) {
// base condition
if (left >= right) {
return;
}
int pivot = arr[right];
int sortedIndex = left;
for (int i = left; i < right; i++) {
if (arr[i] <= pivot) {
swap(arr, i, sortedIndex);
sortedIndex++;
}
}
swap(arr, sortedIndex, right);
quickSort(arr, left, sortedIndex - 1);
quickSort(arr, sortedIndex + 1, right);
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
def quicksort(x):
if len(x) <= 1:
return x
pivot = x[len(x) // 2]
less = []
more = []
equal = []
for a in x:
if a < pivot:
less.append(a)
elif a > pivot:
more.append(a)
else:
equal.append(a)
return quicksort(less) + equal + quicksort(more)
def partition(arr, start, end):
pivot = arr[start]
left = start + 1
right = end
done = False
while not done:
while left <= right and arr[left] <= pivot:
left += 1
while left <= right and pivot <= arr[right]:
right -= 1
if right < left:
done = True
else:
arr[left], arr[right] = arr[right], arr[left]
arr[start], arr[right] = arr[right], arr[start]
return right
def quick_sort(arr, start, end):
if start < end:
pivot = partition(arr, start, end)
quick_sort(arr, start, pivot - 1)
quick_sort(arr, pivot + 1, end)
return arr