반응형
Quick sort
Idea
퀵 정렬은 기본적으로 분할 정복 (Devide and Conquer) 기법과 재귀를 이용한 정렬 알고리즘입니다. Pivot이라는 것을 사용하여 정렬의 기준을 정하게 됩니다. 그리고 그 pivot을 기준으로 “작은 group”, “큰 group”을 나누고, 분할 정복 기법을 이용하여 각각을 해결하는 방식입니다.
6 1 5 11 16 [7] 10 13
위와 같은 숫자 배열을 정렬하고자 할 때, 아무 값이나 pivot으로 선정합니다. 저는 7을 선정하였습니다. pivot을 선정하면, 해당 pivot을 기준으로 작은 값들과 큰 값들을 분류하여 각각 왼쪽, 오른쪽에 위치시킵니다.
6 1 5 [7] 11 16 10 13
그럼, [6,1,5]는 작은 group, [11,16,10,13]은 큰 group이 됩니다. 그럼, 7이라는 pivot은 이제 위치가 고정되게 됩니다. 즉, 정렬이 완료된 것이죠.
이제 각 group에서 pivot을 다시 선정하고, 똑같이 pivot을 기준으로 group을 나눕니다.
작은 group: 임의로 5을 pivot으로 선정
6 1 [5] -> 1 [5] 6
큰 group: 임의로 13을 pivot으로 선정
11 16 10 [13] -> 11 10 [13] 16
여기서 잠시 중간 점검을 하면 아래와 같습니다.
1 5 6 7 11 10 13 16
그럼, 1-5-6-7 까지는 정렬이 완료된 것을 볼 수 있습니다. 이는, 작은 group에서 더 이상 sub problem으로 분할할 수 없기 때문입니다.
과정을 정리하면 아래와 같습니다.
- pivot을 정한다.
- pivot보다 큰 값은 오른쪽에, pivot보다 작은 값은 왼쪽에 둔다.
- pivot을 기준으로 작은 group, 큰 group을 다시 1번 과정부터 더 이상 분할할 수 없을 때까지반복한다.
Code (재귀 사용) - 비효율적
def quick_sort(arr):
if len(arr) <= 1: # 더 이상 분할할 수 없는 경우
return arr
pivot = arr[len(arr) // 2]
lesser_arr, equal_arr, greater_arr = [], [], []
for num in arr:
if num < pivot:
lesser_arr.append(num)
elif num > pivot:
greater_arr.append(num)
else:
equal_arr.append(num)
# 각 group에 대해 재귀 호출
return quick_sort(lesser_arr) + equal_arr + quick_sort(greater_arr)
Code (partition) - 효율적
def quick_sort(arr):
def sort(low, high):
if high <= low:
return
mid = partition(low, high)
sort(low, mid - 1)
sort(mid, high)
def partition(low, high):
pivot = arr[(low + high) // 2]
while low <= high:
while arr[low] < pivot:
low += 1
while arr[high] > pivot:
high -= 1
if low <= high:
arr[low], arr[high] = arr[high], arr[low]
low, high = low + 1, high - 1
return low
return sort(0, len(arr) - 1)
Time complexity
- 쿽 정렬의 성능은 pivot 값을 어떻게 선택하느냐에 크게 달라질 수 있습니다.
- Best Case: pivot 값을 기준으로 동일한 개수의 작은 값들과 큰 값들이 분할되는 경우 → O(nlog(n))의 시간 복잡도를 가진다.
- Worst Case: pivot 값을 기준으로 분할했을 때 값들이 한 편으로 크게 치우는 경우 → O(n^2)의 시간 복잡도를 가진다.
반응형
'Computer Science > Algorithm' 카테고리의 다른 글
[Algorithm] 위상 정렬(Topological sort) 알고리즘 (0) | 2023.01.28 |
---|---|
[Algorithm] 힙 정렬(Heap sort) 알고리즘 (0) | 2023.01.28 |
[Algorithm] 계수 정렬(Counting sort) 알고리즘 (0) | 2023.01.27 |
[Algorithm] 합병 정렬(merge sort) 알고리즘 (0) | 2023.01.23 |
[Algorithm] 선택 정렬, 버블 정렬, 삽입 정렬 알고리즘 (0) | 2023.01.19 |