2018-3-10 TIL Quick Sorting
퀵정렬
[33, 15, 10]의 배열이 있다고 치자. 분할정복을 이용해서 이것을 정렬하기 위해서는 어떻게해야하는가?
- 배열에서 원소를 하나고른다. 이것을 기준원소(pivot)이라고한다. 여기서는 33을 기준원소로 잡았다.
- 이제 모든원소를 기준원소보다 작은원소와 큰원소로 분류를 한다. 15, 10, 33(기준원소) [] 마지막은 빈배열. 이것을 분할이라고 한다.
퀵배열은 다음과 같이 구성이 된다.
- 기준 원소보다 작은 하위 배열
- 기준 원소
- 기준 원소보다 큰 하위 배열
여기서 중요한것은 양쪽에 있는 하위 배열은 정렬이 되어 있지 않다는 것이다!
예시의 경우에는 [10, 15] + [33] + [] = [10, 15, 33]인 경우이다. 이제 원소의 개수를 늘려서 5개로 기준을 늘려보자. [3, 5, 2, 1, 4] 위의 배열은 기준원소를 무엇으로 삼느냐에 따라 5가지 방법으로 달라질 수 있다.
- [1] [3, 5, 2, 4]
- [1] [2] [3, 5, 4]
- [2, 1] [3] [5, 4]
- [3, 2, 1] [4] [5]
- [3, 2, 1, 4] [5] []
- 위의 배열을 통해 모든 하위배열들이 0-4개까지의 원소를 가진것을 알 수 있다. 이것을 n개의 개수인 배열에 일반화를 시키면 n개의 기준원소로 나눌 수 가 있고, 0~n-1까지의 원소를 가진것을 알 수 있다.
어떤 원소를 기준원소로 고르던, 양쪽의 하위 배열에 재귀적으로 퀵 정렬을 하면 된다.
- 예를들어 3을 기준원소로 하면
- qsort([2, 1]) + [3] + qsort([5, 4])
- [1, 2] + [3] + [4, 5]
- [1, 2, 3, 4, 5]
python code
def quicksort(array):
if len(array) < 2:
return array
else:
pivot = array[0]
// 재귀 단계
less = [i for i in array[1:] if i <= pivot]
// 기준원소보다 작거나 같은 하위배열
greater = [i for i in array[1:] if i > pivot]
// 기준원소보다 큰 하위배열
return quicksort(less + [pivot] + greater)
print quicksort([10, 5, 2, 3])
> [2, 3, 5, 10]
퀵정렬은 선택한 기준 원소에 따라 처리속도가 달라지는 특징이 있다. 일반적으로 O(nlogn)을 따른다.
맺으며
- 분할 정복은 문제를 더 작은 조각으로 나누어서 푼다.
- 퀵 정렬을 구현하려면 기준 원소를 무작위로 선택한다. 평균적인 실행시간은 O(n log n)이다.
Written on March 10, 2018