이번 글에서는 퀵 정렬(Quick Sort) 알고리즘에 대해 살펴보도록 하겠습니다. 이 글은 고려대 김선욱 교수님 강의와 위키피디아를 정리하였음을 먼저 밝힙니다. 파이썬 코드 구현은 이곳을 참고하였습니다. 그럼 시작하겠습니다.
티스토리 뷰
퀵 정렬(Quick Sort)
28 Sep 2017 | algorithm
개념
퀵 정렬은 분할정복(divide and conquer) 방식으로 작동합니다. 그 절차는 다음과 같습니다.
- 리스트 가운데서 하나의 원소를 고릅니다. 이를 피벗(pivot)이라 합니다.
- 피벗 앞에는 피벗보다 작은 값, 뒤에는 큰 값이 오도록 하여 리스트를 둘로 분할합니다.
- 분할된 두 개 리스트 각각에 재귀적으로 이 과정을 반복합니다.
퀵 정렬은 분할정복(divide and conquer) 방식으로 작동합니다. 그 절차는 다음과 같습니다.
- 리스트 가운데서 하나의 원소를 고릅니다. 이를 피벗(pivot)이라 합니다.
- 피벗 앞에는 피벗보다 작은 값, 뒤에는 큰 값이 오도록 하여 리스트를 둘로 분할합니다.
- 분할된 두 개 리스트 각각에 재귀적으로 이 과정을 반복합니다.
예시
다음과 같은 리스트를 정렬해보겠습니다.
[5, 3, 7, 6, 2, 1, 4]
첫번째 값(5)을 피벗으로 택해보겠습니다. (마지막 요소 4를 택해도 관계 없습니다) 이 값보다 작은 값들로만 구성된 리스트와 큰 값들로만 구성된 리스트 둘로 분할합니다. 이를 각각 LESSOR와 GREATER라고 명명해보겠습니다.
LESSOR = [3, 2, 1, 4]
GREATER = [7, 6]
그리고 나서 LESSOR와 GREATER 각각에 같은 작업을 해당 리스트의 요소 개수가 하나가 될 때까지 재귀적으로 반복합니다.
다음과 같은 리스트를 정렬해보겠습니다.
[5, 3, 7, 6, 2, 1, 4]
첫번째 값(5)을 피벗으로 택해보겠습니다. (마지막 요소 4를 택해도 관계 없습니다) 이 값보다 작은 값들로만 구성된 리스트와 큰 값들로만 구성된 리스트 둘로 분할합니다. 이를 각각 LESSOR와 GREATER라고 명명해보겠습니다.
LESSOR = [3, 2, 1, 4]
GREATER = [7, 6]
그리고 나서 LESSOR와 GREATER 각각에 같은 작업을 해당 리스트의 요소 개수가 하나가 될 때까지 재귀적으로 반복합니다.
구현
퀵 정렬을 파이썬으로 구현한 코드는 다음과 같습니다.
퀵 정렬을 파이썬으로 구현한 코드는 다음과 같습니다.
def quick_sort(arr):
size = len(arr)
if size <= 1:
return arr
else:
pivot = arr[0]
greater = [element for element in arr[1:] if element > pivot]
lesser = [element for element in arr[1:] if element <= pivot]
return quick_sort(lesser) + [pivot] + quick_sort(greater)
계산복잡성
퀵 정렬의 계산복잡성은 피벗을 어떻게 선택하느냐에 따라 달라집니다. 최악의 경우는 다음과 같습니다. 다시 말해 피벗의 왼쪽(LESSOR) 요소가 매번 하나인 경우입니다. 이렇게 되면 높이가 , 각 층에서 개의 요소에 대해 정렬을 수행해야 하므로 의 계산복잡도를 가지게 됩니다.
가장 좋은 경우는 다음과 같습니다. 분할 과정이 다음과 같이 균형적이어서, 계산 트리의 높이가 에서 으로 줄어들게 되기 때문입니다. 이렇게 되면 높이가 , 각 층에서 개의 요소에 대해 정렬을 수행해야 하므로 의 계산복잡도를 가지게 됩니다.
Average case의 경우에도 퀵 정렬은 의 계산복잡도를 가진다고 합니다. 아울러 피벗을 선택할 때 정해진 위치가 아니라 랜덤하게 선택하거나, 몇 개 값을 랜덤 샘플링해 이 값들의 중앙값(median)에 가까운 값을 피벗으로 정하면 계산복잡도를 다소 낮추는 데 도움이 된다고 합니다.
퀵 정렬의 특징
설명의 편의를 위해 피봇을 기준으로 작은 값을 왼쪽, 나머지를 오른쪽으로 보내는 과정을 재귀적으로 반복한다고 했습니다만, original code는 이보다는 살짝 더 복잡합니다. 정렬 수행 과정에서 별도 저장 공간을 필요로 하지 않는 in-place sort를 지향하고자 하기 때문인데요. original code의 수행 과정을 보시려면 이곳을 참고하시면 좋을 것 같습니다. 수행과정을 도식화하면 다음 그림과 같습니다. 이 과정에서 같은 값의 상대적 위치가 바뀔 수 있습니다(unstable sort).
'python lecture > algorism' 카테고리의 다른 글
[edu] 올바른 괄호 (0) | 2019.01.17 |
---|---|
[edu] 행렬의 곱셈 (0) | 2018.12.21 |
[edu] 10진수 > n진수 변환 (0) | 2018.12.19 |
[edu] queue (with node) (0) | 2018.12.11 |
[edu] double linked list (with node) (0) | 2018.12.09 |
- Total
- Today
- Yesterday
- chatbot
- django
- 면접정답
- 파이썬 입문
- django chatbot
- gitlab
- PuTTYGen
- 플러스친구 자동응답
- 문서 비교
- 엑셀 비교
- 파이썬 강좌
- 파이썬 독학
- 파이썬
- GIT
- gitignore
- 이미지 비교
- 장고
- 장고 카톡 자동응답
- 장고 플러스친구 자동응답
- 모바일 스킨 적용
- 모바일 테마 적용
- 파이썬 프로그래밍
- Python
- 문과 코딩
- wsgi
- pycrypto
- admin.py
- Tistory
- 면접답변
- virtualenv
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |