대표적인 정렬의 종류
1) O(n²)의 시간 복잡도
- 버블 정렬(Bubble Sort) : 바로 옆에 있는 것과 비교해서 정렬함. 구현은 쉽지만 효율성이 매우 낮다고 알려짐.
- 선택 정렬(Selection Sort) : 가장 작은 데이터를 선택해서 정렬되지 않은 데이터 중 가장 앞 쪽에 있는 데이터와 위치를 바꾸는 방법
- 삽입 정렬(Insertion Sort) : 데이터를 앞에서부터 하나씩 확인하며 데이터를 적절한 위치에 삽입하는 방법
2) O(n log n)의 시간 복잡도 : divide and conquer
- 합병 정렬, 병합 정렬(Merge Sort)
- 퀵 정렬(Quick Sort) : 기준 데이터를 설정하고 그 기준보다 큰 데이터와 작은 데이터의 위치를 바꾸는 방법, 최악의 경우는 O(n²)이지만 평균적으로 O(n log n)
- 힙 정렬(Heap Sort) : 최대 힙 트리나 최소 힙 트리를 구성해 정렬을 하는 방법으로서, 내림차순 정렬을 위해서는 최소 힙을 구성하고 오름차순 정렬을 위해서는 최대 힙을 구성함.
- 힙이란? (최소 힙 기준)
- 부모 노드의 키가 자식 노드의 키보다 작게 구성된 완전 이진 트리, 중복 값을 허용함.
- 파이썬의 heapq 모듈을 통해 사용 가능
- heapq 모듈은 이진 트리(binary tree) 기반의 최소 힙(min heap) 자료구조를 제공
- heapq.heapify(heap) : 이미 원소가 들어있는 리스트 → 힙 구조로 재구성, O(n)
- heapq.heappop(heap) : 힙의 가장 작은 원소를 삭제 후에 그 값을 리턴함. O(log n)
- heapq.heappush(heap, element) : 힙에 원소를 추가함. O(log n)
- 최대 힙
- 힙에 튜플(tuple)를 원소로 추가하거나 삭제하면, 튜플 내에서 맨 앞에 있는 값을 기준으로 최소 힙이 구성되는 원리를 이용
- 힙이란? (최소 힙 기준)
# 최대 힙 만들기
from heapq import heappush, heappop
nums = [4, 1, 7, 3, 8, 5]
heap = []
for num in nums:
heappush(heap, (-num, num)) # (우선 순위, 값)
while heap:
print(heappop(heap)[1]) # index 1
정렬 알고리즘 평균 시간 복잡도 및 공간 복잡도 특징
정렬 알고리즘 | 시간복잡도 | 공간복잡도 | 특징 |
선택 정렬 | O(n²) | O(n) | 아이디어가 간단하나, 효율은 낮음. |
삽입 정렬 | O(n²) | O(n) | 데이터가 거의 정렬되어 있을 때는 가장 빠름. |
퀵 정렬 | O(n log n) | O(n) | 대부분의 경우 가장 적합, 충분히 빠름. |
계수 정렬 | O(n + k) | O(n + k) | 특정한 값을 가지는 데이터의 개수를 카운트하는 방법 데이터의 크기가 한정되어 있는 경우에만 사용이 가능, 매우 빠르게 동작 |
import random
class Sort :
def bubble_sort(arr):
for i in range(len(arr)):
for j in range(len(arr) - i - 1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
def selection_sort(arr):
for i in range(len(arr)):
min_index = i
for j in range(i+1, len(arr)):
if arr[min_index] > arr[j]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left, right, equal = [], [], []
for i in arr:
if i < pivot:
left.append(i)
elif i > pivot:
right.append(i)
else:
equal.append(i)
return quick_sort(left) + equal + quick_sort(right)
def merge_sort(arr):
if len(arr) < 2:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
merged_arr = []
l = r = 0
while l < len(left) and r < len(right):
if left[l] < right[r]:
merged_arr.append(left[l])
l += 1
else:
merged_arr.append(right[r])
r += 1
merged_arr += left[l:]
merged_arr += right[r:]
return merged_arr
def heap_sort(arr):
def heapify(arr, n, i):
largest = i
l = 2 * i + 1
r = 2 * i + 2
if l < n and arr[i] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
n = len(arr)
for i in range(n, -1, -1):
heapify(arr, n, i)
for i in range(n-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i]
heapify(arr, i, 0)
return arr
def radix_sort(arr):
RADIX = 10
placement = 1
max_digit = max(arr)
while placement < max_digit:
buckets = [list() for _ in range(RADIX)]
for i in arr:
tmp = int((i / placement) % RADIX)
buckets[tmp].append(i)
a = 0
for b in range(RADIX):
buck = buckets[b]
for i in buck:
arr[a] = i
a += 1
placement *= RADIX
return arr
def counting_sort(arr):
max_value = max(arr)
m = max_value + 1
count = [0] * m
for a in arr:
count[a] += 1
i = 0
for a in range(m):
for c in range(count[a]):
arr[i] = a
i += 1
return arr
arr = [i for i in random.sample(range(10), 10)]
print("Original array: ", arr)
print("Bubble sort: ", Sort.bubble_sort(arr))
print("Selection sort: ", Sort.selection_sort(arr))
print("Quick sort: ", Sort.quick_sort(arr))
print("Merge sort: ", Sort.merge_sort(arr))
print("Heap sort: ", Sort.heap_sort(arr))
print("Radix sort: ", Sort.radix_sort(arr))
print("Counting sort: ", Sort.counting_sort(arr))
파이썬의 정렬 알고리즘
list.sort()
sorted(list)
- list.sort() : 입력값으로는 리스트 밖에 받지 못함. 리스트 원본 값을 직접 수정함. 원본이 필요없을 때는 시간, 공간 절약함.
- sorted(list) : 내장함수로 리스트 원본 값은 그대로 유지함. 어떤 입력값이든 받을 수 있음. 원본을 유지해야 할 때 사용함.
- Timesort 알고리즘 : 삽입 정렬과 병합 정렬을 결합한 Hybrid stable sorting 알고리즘으로 어느 정도 정렬된 부분이 존재하는 실생활 데이터의 특성을 고려해 더 빠르게 작동하도록 고안한 알고리즘
- 최선 : O(n), 평균 및 최악 : O(n log n)
'이론' 카테고리의 다른 글
[알고리즘 코테] DFS/BFS (0) | 2024.02.03 |
---|---|
[패스트캠퍼스 - 30개 프로젝트로 끝내는 추천시스템 강의 Chapter10. 기획안 기반 추천시스템 개발 실습] (1) | 2024.01.28 |
[알고리즘 코테] 그리디 (0) | 2023.11.12 |
[패스트캠퍼스 - 30개 프로젝트로 끝내는 추천시스템 강의 Chapter06. 추천시스템이 필요한 이유] (0) | 2023.10.29 |
[SQLD 1과목 요점정리] (0) | 2023.09.03 |