입력크기 n일 때,
총 분할 횟수
k =log n
1. a개로 분할, 1/b로 감소
2. a=2, b=일정 X 감소
3. a=2(2개 중 하나는 무시), 1/2로 감소
4. a=2(2개 중 하나는 무시), b=일정 X 감소
5. b=1, 2개씩 감소
- 배열 원소 수 2개 이상일 때(1개일 때까지) 반으로 나눈다.
- 파이프 앞에서 원소를 하나씩 빼서 비교한 후, 새 파이프에 정리한다는 느낌으로 정렬된 부분 배열을 합병한다.
Pseudo-code
MergeSort(A, p, q): #배열 A, 첫 인덱스 p, 끝 인덱스 q
if p < q: #배열 내 원소가 2개 이상일 때
k = (p + q) // 2 #절반 위치 인덱스(몫만 취함)
MergeSort(A, p, k) #앞부분 순환 호출
MergeSort(A, k + 1, q) # 뒷부분 순환 호출
Merge(A, p, q) #부분 배열 합병 정렬
O(nlogn)
O(n)
1. 배열에 원소 2개 이상 있을 경우,
1-1. 배열 A[left] ~ A[right] 중 피벗 선택
1-2. SWAP(A[left], 피벗);
1-3. 피벗보다 작은 숫자들은 왼편, 큰 숫자는 오른편으로 옮기기
2. 피벗보다 작은 그룹 1번 과정 순환
3. 피벗보다 큰 그룹 1번 과정 순환
Python
def quick_sort(arr, start, end):
if start >= end: return
pivot = arr[start] # 피벗은 첫번째 원소
l, r = start + 1, end
while l <= r:
while l <= end and arr[l] <= arr[pivot]:
l += 1
while r > start and arr[r] >= arr[pivot]:
r -= 1
if l > r:
arr[r], arr[pivot] = arr[pivot], arr[r]
else:
arr[r], arr[l] = arr[l], arr[r]
quick_sort(arr, start, r - 1)
quick_sort(arr, r + 1, end)
A = [5, 3, 8, 4, 9, 1, 6, 2, 7, 10]
print(quick_sort(A, 0, len(A)))
O(n^2)
- 피벗이 최소/최대
숫자일 경우O(nlog n)
- 분할이 절반으로 이루어질 때(=합병 정렬)O(nlog n)
퀵 정렬의 성능은 피벗이 좌우!
- 랜덤 선정
- 세 값의 median
pivot = median{K[l], K[(l+r)/2], K[r]}