Tags
- 이진트리
- 완전검색
- migrations
- 큐
- 뷰
- DB
- drf
- regexp
- M:N
- Tree
- N:1
- 통계학
- stack
- update
- Queue
- 트리
- Article & User
- 스택
- delete
- Django
- count
- 쟝고
- outer join
- Vue
- 백트래킹
- distinct
- create
- SQL
- 그리디
- ORM
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Notice
Recent Posts
Link
데이터 분석 기술 블로그
힙 정렬 (Heap Sort) 본문
힙 정렬
"힙(Heap) 자료구조를 이용해 정렬하는 알고리즘"
- 완전 이진 트리(Complete Binary Tree) 기반의 힙(Heap) 구조 사용
- 최대 힙(Max Heap) → 내림차순 정렬 / 최소 힙(Min Heap) → 오름차순 정렬
- 시간복잡도 O(n log n) → 퀵 정렬처럼 빠르지만, 안정 정렬(Stable Sort)이 아님
- 제자리 정렬(In-place Sort) 가능 → 추가 메모리 사용 X (O(1))
2025.01.20 - [데이터 사이언스/알고리즘] - 완전 이진 트리 (Complete Binary Tree)
힙 정렬의 동작 원리
- 힙 생성(Heapify) → 주어진 배열을 힙 구조로 변환
- 최댓값(또는 최솟값) 추출 → 루트 노드(가장 큰/작은 값)를 배열의 끝으로 이동
- 힙 속성 복구 → 남은 힙을 다시 정렬하고 반복
2025.01.20 - [데이터 사이언스/알고리즘] - Heapify
힙 정렬의 시간복잡도
경우 | 시간복잡도 |
최선 (이미 정렬됨) | O(n log n) |
평균 | O(n log n) |
최악 (역순 정렬) | O(n log n) |
✅ 퀵 정렬과 달리, 최악의 경우에도 O(n log n) 성능 유지!
✅ 추가 메모리 사용 없이 O(1) 공간복잡도로 정렬 가능!
# Pseudo Code
FUNCTION HeapSort(arr)
n = length(arr)
# 1. 주어진 배열을 최대 힙으로 변환 (Heapify)
FOR i FROM (n // 2) DOWNTO 0 DO
Heapify(arr, n, i)
# 2. 힙에서 최대값을 하나씩 꺼내 정렬
FOR i FROM n-1 DOWNTO 1 DO
SWAP arr[0] AND arr[i] # 루트(최대값)를 마지막으로 이동
Heapify(arr, i, 0) # 힙 크기를 줄이고 다시 Heapify 실행
END FUNCTION
FUNCTION Heapify(arr, n, i)
largest = i # 현재 부모 노드
left = 2 * i + 1 # 왼쪽 자식 노드
right = 2 * i + 2 # 오른쪽 자식 노드
# 왼쪽 자식이 존재하고, 부모보다 크다면 largest 갱신
IF left < n AND arr[left] > arr[largest] THEN
largest = left
# 오른쪽 자식이 존재하고, 가장 큰 값보다 크다면 largest 갱신
IF right < n AND arr[right] > arr[largest] THEN
largest = right
# 부모가 가장 큰 값이 아니라면 Swap 실행 후, Heapify 재귀 호출
IF largest != i THEN
SWAP arr[i] AND arr[largest]
Heapify(arr, n, largest)
END FUNCTION
# Full Code
def heapify(arr, n, i):
largest = i # 부모 노드 인덱스
left = 2 * i + 1 # 왼쪽 자식 노드
right = 2 * i + 2 # 오른쪽 자식 노드
# 왼쪽 자식이 부모보다 크다면 largest 업데이트
if left < n and arr[left] > arr[largest]:
largest = left
# 오른쪽 자식이 가장 크다면 largest 업데이트
if right < n and arr[right] > arr[largest]:
largest = right
# 부모가 가장 크지 않다면 Swap 실행 후, 재귀적으로 Heapify 실행
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)
# 1. 최대 힙(Max Heap) 생성
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# 2. 힙에서 하나씩 꺼내 정렬
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # 최대값을 끝으로 이동
heapify(arr, i, 0) # 힙 크기 줄이고 Heapify 실행
# 테스트
arr = [10, 9, 5, 8, 3, 2, 1, 6, 7, 4]
heap_sort(arr)
print("힙 정렬 결과:", arr)
장점
- 최악의 경우에도 O(n log n) 보장 (퀵 정렬보다 안정적)
- 제자리 정렬 가능 → 추가적인 메모리(O(1))만 사용
- 큰 데이터셋에서도 안정적인 성능 유지
단점
- Stable Sort(안정 정렬)이 아님 → 같은 값의 순서가 유지되지 않음
- 힙 구성(Heapify) 과정에서 연산량이 많아 실제 성능은 퀵 정렬보다 느릴 수도 있음
- 캐시 효율성이 낮아 실제 실행 속도가 퀵 정렬보다 떨어질 수 있음
결론
힙 정렬은 퀵 정렬보다 안정적인 O(n log n) 성능을 보장하지만, 실제 실행 속도는 퀵 정렬보다 느릴 수도 있습니다.
'데이터 사이언스 > 알고리즘' 카테고리의 다른 글
Heapify (0) | 2025.02.19 |
---|---|
완전 이진 트리 (Complete Binary Tree) (0) | 2025.02.18 |
병합 정렬 (Merge Sort) (0) | 2025.02.16 |
Heap Overflow (0) | 2025.02.15 |
Stack Overflow (0) | 2025.02.14 |