퀵정렬은 효율적인 정렬 알고리즘 중 하나로, 다음과 같은 기본 아이디어에 기반하여 동작합니다:
퀵정렬의 원리와 동작 방식에 대해 좀 더 상세하게 설명하겠습니다.
피벗 선택
분할
left
와 right
라는 두 개의 포인터를 사용하여 수행됩니다. left
포인터는 배열의 왼쪽에서 오른쪽으로 이동하면서 피벗보다 큰 요소를 찾고, right
포인터는 배열의 오른쪽에서 왼쪽으로 이동하면서 피벗보다 작은 요소를 찾습니다. 두 포인터가 교차할 때까지 이 과정이 반복됩니다.right
포인터가 가리키는 요소를 교환합니다.재귀적 정렬
퀵정렬은 최선의 경우, 평균의 경우 O(n log n)의 시간 복잡도를 가지지만 최악의 경우 O(n^2)의 시간 복잡도를 가질 수 있습니다. 평균적으로 선택정렬, 삽입정렬, 버블정렬에 비해 빠른 속도를 보여줍니다.
위에서 설명한 퀵 정렬 알고리즘을 파이썬 코드를 통해 살펴 보겠습니다. 다음 예제는 '제로베이스 데이터스쿨' 강의를 참고하였습니다.
def quick_sort(lst, start, end, reverse=False):
if start >= end:
return
pivot = start
left = start + 1
right = end
while left <= right:
while (not reverse and (left <= end) and (lst[left] <= lst[pivot])) or\
(reverse and (left <= end) and (lst[left] >= lst[pivot])):
left += 1
while (not reverse and (right > start) and (lst[right] >= lst[pivot])) or\
(reverse and (right > start) and (lst[right] <= lst[pivot])):
right -= 1
if left > right:
lst[right], lst[pivot] = lst[pivot], lst[right]
else:
lst[left], lst[right] = lst[right], lst[left]
quick_sort(lst, start, right - 1, reverse)
quick_sort(lst, right + 1, end, reverse)
quick_sort
함수는 퀵정렬을 수행하는 주요 함수입니다. 이 함수는 재귀적으로 호출되어 정렬을 수행합니다.퀵정렬 함수 정의:
def quick_sort(lst, start, end, reverse=False):
quick_sort
는 퀵정렬 알고리즘을 구현한 함수입니다.lst
는 정렬할 리스트, start
는 시작 인덱스, end
는 마지막 인덱스입니다.reverse
는 선택적 매개변수로, 기본적으로 False
로 설정되어 있습니다. 이는 정렬 방향을 결정하는데 사용됩니다.재귀의 종료 조건:
if start >= end:
return
start
가 end
보다 크거나 같으면 더 이상 정렬할 요소가 없으므로 함수를 종료합니다.포인터 초기화 및 분할 과정:
pivot = start
left = start + 1
right = end
start
인덱스의 요소로 설정됩니다. (이 코드에서는 항상 첫 번째 요소가 피벗으로 선택됩니다.)left
포인터는 피벗 바로 다음 요소부터 시작하고, right
포인터는 리스트의 마지막 요소에서 시작합니다.분할 과정:
while left <= right:
left
포인터와 right
포인터가 교차하기 전까지 반복합니다.피벗과의 비교 및 포인터 이동:
while (not reverse and (left <= end) and (lst[left] <= lst[pivot])) or\
(reverse and (left <= end) and (lst[left] >= lst[pivot])):
left += 1
while (not reverse and (right > start) and (lst[right] >= lst[pivot])) or\
(reverse and (right > start) and (lst[right] <= lst[pivot])):
right -= 1
left
포인터는 피벗보다 큰 요소를 찾을 때까지 오른쪽으로 이동합니다.right
포인터는 피벗보다 작은 요소를 찾을 때까지 왼쪽으로 이동합니다.포인터의 위치에 따른 분할 및 교환:
if left > right:
lst[right], lst[pivot] = lst[pivot], lst[right]
else:
lst[left], lst[right] = lst[right], lst[left]
left
포인터가 right
포인터보다 오른쪽에 위치한다면, 피벗과 right
포인터 위치의 요소를 교환합니다.left
와 right
포인터 위치의 요소를 교환합니다.재귀적 호출:
quick_sort(lst, start, right - 1, reverse)
quick_sort(lst, right + 1, end, reverse)
정방향 및 역방향 정렬:
reverse
매개변수를 사용하여 오름차순(정방향) 또는 내림차순(역방향)으로 정렬할 수 있습니다. reverse
의 값에 따라 비교 연산자가 바뀌어 적절한 방향으로 정렬을 수행합니다.quick_sort
함수는 피벗을 기준으로 배열을 분할하고, 분할된 각 부분 배열에 대해 재귀적으로 같은 알고리즘을 적용함으로써 전체 배열을 정렬하는 방식으로 동작합니다.