시간복잡도가 O(NlogN)인 정렬은 퀵 정렬, 병합 정렬, 힙 정렬이 있다.
해당 정렬들은 시간복잡도가 O(N^2)인 정렬보다 대체로 구현하기 어렵다.
👇 퀵 정렬
→ 분명한 반복적인 패턴이 있기 때문에 재귀를 이용해서 구현한다.
def quick_sort(arr):
if not arr:
return arr
# 임의로 하나의 피벗을 지정하며 해당 경우는 배열의 마지막 원소
pivot = arr.pop()
left = []
right = []
# 반복문을 사용해서 피벗 기준으로 배열을 2개로 나눔
for i in range(len(arr)):
if arr[i] < pivot:
left.append(arr[i])
else:
right.append(arr[i])
return quick_sort(left) + [pivot] + quick_sort(right)
퀵 정렬과 마찬가지로 합병 정렬은 분할 정복 기법(divide and conquer)을 사용한 정렬이다. 일반적인 방법으로 구현했을 때 이 정렬은 안정 정렬에 속한다.
퀵 정렬과의 차이점은 퀵, 정렬의 경우 가장 큰 부분 리스트로부터 시작해서 가장 작은 부분 리스트에서 종료되지만 합병 정렬의 경우 가장 작은 부분 리스트로부터 시작해서 가장 큰 부분 리스트에서 종료된다.
퀵 정렬 - 스택 필요, 불안정적인 정렬, 정복 → 분할
합병 정렬 - 스택 불필요, 안정적인 정렬 (같은 값이어도 정렬 후 순서가 변하지 않음), 분할 → 정복
👇 합병 정렬
def merge_sort(arr):
if len(arr) < 2:
return arr
mid = len(arr) // 2
low_arr = merge_sort(arr[:mid])
high_arr = merge_sort(arr[mid:])
merged_arr = []
low = high = 0
while low < len(low_arr) and high < len(high_arr):
if low_arr[low] < high_arr[high]:
merged_arr.append(low_arr[low])
low += 1
else:
merged_arr.append(high_arr[high])
high += 1
merged_arr += low_arr[low:]
merged_arr += high_arr[high:]
return merged_arr
최대 힙 트리나 최소 힙 트리를 구성해 정렬하는 방법으로, 내림차순 정렬을 위해서는 최대 힙을 구성하고 오름차순 정렬을 위해서는 최소 힙을 구성한다.
👉 힙 정렬은 주어진 리스트를 최대 힙의 자료구조 형태로 만들고 정렬을 하는 것이다. 힙의 자료구조에서 배열의 첫 번째에는 배열의 가장 큰 수가 오게 된다. 그 후에는 배열의 첫 번째 원소를 가장 뒤로 보내고, 배열의 가장 마지막 원소를 제외한 배열을 다시 최대 힙을 만들어주는 것이다.
👇 힙 정렬
📌 완전이진트리 - 노드를 부모노드 → 왼쪽 자식노드 → 오른쪽 자식노드 순서로 추가한 이진 트리
# 최대 힙을 만들어주는 함수
def heapify(arr, index, heap_size):
# 부모와 자식 노드의 index 간에 성립하는 식
largest = index
left_index = 2*index + 1
right_index = 2*index + 2
if left_index < heap_size and arr[left_index] > arr[largest]:
largest = left_index
if right_index < heap_size and arr[right_index] > arr[largest]:
largest = right_index
if largest != index:
arr[largest], arr[index] = arr[index], arr[largest]
heapify(arr, largest, heap_size)
def heap_sort(arr)
for i in range(len(arr) // 2-1, -1, -1):
heapify(arr, i, len(arr))
for i in range(len(arr)-1, 0, -1):
arr[0], arr[i] = ls[i], arr[0]
heapify(arr, 0, i)
return arr
https://velog.io/@supergangho/4-Python-Onlogn-%EC%A0%95%EB%A0%AC%ED%80%B5-%EB%B3%91%ED%95%A9-%ED%9E%99
https://lsh424.tistory.com/69
https://ko.wikipedia.org/wiki/%ED%80%B5_%EC%A0%95%EB%A0%AC
https://ko.wikipedia.org/wiki/%ED%9E%99_%EC%A0%95%EB%A0%AC
https://ko.wikipedia.org/wiki/%ED%95%A9%EB%B3%91_%EC%A0%95%EB%A0%AC
(도서) 이것이 코딩 테스트다 with Python