정렬 알고리즘은 데이터의 양, 정렬된 정도, 최적/ 평균/ 최악 조건에서의 성능, 메모리 사용 등 상황에 맞게 쓰인다.
(어떤 것이 최고라고 말할 수 없음)
시간 복잡도 O(n^2)
def bubble_sort(lst):
LEN = len(lst)
for last_idx in range(LEN-2, 0, -1): # 각 턴의 마지막 인덱스
is_swap = False # 최적화
for l_idx in range(0, last_idx+1):
if lst[l_idx] > lst[l_idx+1]:
lst[l_idx], lst[l_idx+1] = lst[l_idx+1], lst[l_idx]
is_swap = True
if not is_swap: # swap이 일어나지 않았으면 정렬 완료상태
return lst
return lst
시간 복잡도 O(n^2)
맞바꾸는 횟수는 O(n)이기 때문에 복사 연산이 매우 느린 경우 적합
def select_sort(lst):
LEN = len(lst)
for cur_idx in range(0, LEN-1): # 최소값을 위치시킬 인덱스
search_start, min_idx = cur_idx+1, cur_idx
for search_idx in range(search_start, LEN):
if lst[search_idx] < lst[min_idx]:
min_idx = search_idx
lst[cur_idx], lst[min_idx] = lst[min_idx], lst[cur_idx]
return lst
시간 복잡도 O(n^2)
이미 정렬된 데이터 집합에 대해 매우 효율적
def insert_sort(lst):
LEN = len(lst)
for search_start in range(1, LEN): # 탐색 시작 인덱스
while search_start > 0:
if lst[search_start] < lst[search_start-1]:
lst[search_start], lst[search_start - 1] \
= lst[search_start-1], lst[search_start]
search_start -= 1
else:
break
return lst
시간 복잡도 O(nlogn)
분할 정복 알고리즘
최악의 경우 - O(n^2) ; pivot 값이 맨 왼쪽값으로 설정되고 정렬되어 있는 경우
def quick_sort(lst):
LEN = len(lst)
if LEN <= 1:
return lst
middle = len(lst) // 2 # 최악의 케이스를 막기 위해 pivot을 middle로 설정
pivot = lst[middle]
rest = lst[:middle] + lst[middle+1:]
left = [num for num in rest if num <= pivot]
right = [num for num in rest if num > pivot]
return quickSort(left) + [pivot] + quickSort(right)
참고 : 최적화된 퀵정렬
인덱스 두개를 사용하여 탐색 후 맞바꿈
시간 복잡도 O(nlogn)
분할 정복 알고리즘, 어떤 조건에서도 O(nlogn), 메모리에 전부 집어넣을 수 없는 데이터 집합 정렬 시 유용
def merge(left, right):
merged = []
while left or right:
# left나 right 가 비었을 때
if not left:
merged += right
return merged
elif not right:
merged += left
return merged
# left나 right 첫번째 원소값 비교
if left[0] < right[0]:
merged += [left[0]]
left = left[1:]
else:
merged += [right[0]]
right = right[1:]
return merged
def merge_sort(lst):
LEN = len(lst)
if LEN <= 1:
return lst
middle = len(lst) // 2
left = merge_sort(lst[:middle])
right = merge_sort(lst[middle:])
return merge(left, right)