병합 정렬
- 원리: 데이터를 반으로 나누어 정렬 후 병합
- 특징: 안정적인 정렬이며, 추가적인 메모리 공간 필요
- 공간 복잡도: O(n)
- 시간 복잡도: O(n log n)
- 예시
- 최초에는 8개의 그룹으로 나눔
- 이 상태에서 2개씩 그룹을 합치며 오름차순 정렬
- 투 포인터 개념을 사용하여 왼쪽, 오른쪽 그룹을 병합함
- 왼쪽 포인터와 오른쪽 포인터의 값을 비교하여 작은 값을 배열에 추가하고 포인터를 오른쪽으로 1칸 이동시킴
[5, 3, 8, 2, 4, 1, 6, 7] → [5], [3], [8], [2], [4], [1], [6], [7] → [3, 5], [2, 8], [1, 4], [6, 7] → [2, 3, 5, 8], [1, 4, 6, 7] // 여기 병합 기준으로 설명 → [1, 2, 3, 4, 5, 6, 7, 8]
- 왼쪽 배열: [2, 3, 5, 8], 오른쪽 배열: [1, 4, 6, 7] → 각각 배열의 포인터를 둠
- 첫 번째 비교
- 왼쪽 포인터: 0 → 값: 2
- 오른쪽 포인터: 0 → 값: 1
- 새로운 배열 [1]
- 두 번째 비교
- 왼쪽 포인터: 0 → 값: 2
- 오른쪽 포인터: 1 → 값: 4
- 새로운 배열 [1, 2]
- 세 번째 비교
- 왼쪽 포인터: 1 → 값: 3
- 오른쪽 포인터: 1 → 값: 4
- 새로운 배열 [1, 2, 3]
- 네 번째 비교
- 왼쪽 포인터: 2 → 값: 5
- 오른쪽 포인터: 1 → 값: 4
- 새로운 배열 [1, 2, 3, 4]
- 다섯 번째 비교
- 왼쪽 포인터: 2 → 값: 5
- 오른쪽 포인터: 2 → 값: 6
- 새로운 배열 [1, 2, 3, 4, 5]
- 여섯 번째 비교
- 왼쪽 포인터: 3 → 값: 8
- 오른쪽 포인터: 2 → 값: 6
- 새로운 배열 [1, 2, 3, 4, 5, 6]
- 일곱 번째 비교
- 왼쪽 포인터: 3 → 값: 8
- 오른쪽 포인터: 3 → 값: 7
- 새로운 배열 [1, 2, 3, 4, 5, 6, 7]
- 오른쪽 배열을 모두 정렬시켰으므로, 이후 왼쪽 배열을 순서대로 새로운 배열에 추가
- 새로운 배열 [1, 2, 3, 4, 5, 6, 7, 8]
퀵 정렬
- 원리: 기준점(피벗)을 설정하고, 피벗보다 작은 데이터는 왼쪽, 큰 데이터는 오른쪽으로 분할하여 정렬
- 특징: 분할 정복 방식으로 동작하며, 실제로 가장 빠르게 동작하는 경우가 많음
- 공간 복잡도: 필요 없음
- 시간 복잡도: O(n log n)
- 최악의 시간 복잡도: O(n^2) (피벗 선택이 비효율적인 경우)
- 예시
[3, 2, 5, 4, 1] (피벗: 3)
→ [2, 1] [3] [5, 4] // 1
→ [1, 2] [3] [4, 5] // 2
→ [1, 2, 3, 4, 5] // 3
-
- 피벗(3) 기준으로 왼쪽은 피벗 보다 작은 데이터, 오른쪽은 피벗보다 큰 데이터 (분할)
- 피벗: [3]
- 작은 데이터: [2, 1]
- 큰 데이터: [5, 4]
- 각 데이터 배열을 정렬
- 피벗: [3]
- 작은 데이터: [1, 2]
- 큰 데이터: [4, 5]
- 데이터 배열 병합
- [1, 2, 3, 4, 5]
- 피벗(3) 기준으로 왼쪽은 피벗 보다 작은 데이터, 오른쪽은 피벗보다 큰 데이터 (분할)
기수 정렬
- 원리: 자릿수별로 데이터를 비교하여 정렬, 낮은 자릿수부터 높은 자릿수까지 진행함
- 특징: 바교를 사용하지 않음, 정수 또는 고정 길이의 문자열에 적합
- 시간 복잡도: O(nk) (k: 자릿수의 길이)
- 예시
- 대상 데이터: [16, 80, 18, 77, 03, 24, 88, 23]
- 기수 정렬은 자릿수를 기준으로 비교하기 때문에 10개의 큐를 사용
- → 각 자릿수는 0~9까지의 수로 이루어지기 때문
- 1의 자릿수 큐는 0 ~ 9까지의 큐로 이루어짐
- 16부터 1의 자릿수를 비교하여 해당 큐에 삽입
- 16: 6번째 큐
- 80: 0번째 큐
- 18: 8번째 큐
- 77: 7번째 큐
- 03: 3번째 큐
- 24: 4번째 큐
- 88: 8번째 큐
- 23: 3번째 큐
- 0번째 큐: [80]
- 1번째 큐: []
- 2번째 큐: []
- 3번째 큐: [03, 23]
- 4번째 큐: [24]
- 5번째 큐: []
- 6번째 큐: [16]
- 7번째 큐: [77]
- 8번째 큐: [18, 88]
- 9번째 큐: []
- 순서대로 10의 자리 수 큐로 이동
- 80: 8번째 큐
- 03: 0번째 큐
- 23: 2번째 큐
- 24: 2번째 큐
- 16: 1번째 큐
- 77: 7번째 큐
- 18: 1번째 큐
- 88: 8번째 큐
- 0번째 큐: [03]
- 1번째 큐: [16, 18]
- 2번째 큐: [23, 24]
- 3번째 큐: []
- 4번째 큐: []
- 5번째 큐: []
- 6번째 큐: []
- 7번째 큐: [77]
- 8번째 큐: [80, 88]
- 9번째 큐: []
- 순서: [80, 03, 23, 24, 16, 77, 18, 88 ] → 이 순서는 적어도 1의 자리 수는 정렬되어 있음
→ 최종 정렬 데이터: 0번째 큐부터 꺼내기
[03, 16, 18, 23, 24, 77, 80, 88]
'알고리즘(Swift)' 카테고리의 다른 글
알고리즘(Swift) - DP(다이나믹 프로그래밍) 알고리즘 (0) | 2025.01.10 |
---|---|
알고리즘(Swift) - 그리디 알고리즘(탐욕 알고리즘) (0) | 2025.01.09 |
알고리즘 - 정렬 알고리즘 (선택 정렬, 삽입 정렬, 버블 정렬) (1) | 2025.01.06 |
알고리즘(Swift) - 유클리드 알고리즘 (0) | 2025.01.03 |
알고리즘(Swift) - 에라토스테네스의 체 알고리즘 (0) | 2025.01.02 |