팀 정렬(Tim Sort)은 2002년 팀 피터스(Tim Peters)가 개발한 정렬 알고리즘으로, 파이썬의 기본 정렬 알고리즘으로 채택되었습니다. 팀 정렬은 합병 정렬(Merge Sort)과 삽입 정렬(Insertion Sort)의 장점을 결합한 하이브리드 알고리즘으로, 실제 데이터에서 매우 효율적입니다. 팀 정렬은 분할 정복 기법을 사용하며, 데이터의 부분 정렬(run)을 찾고 이를 병합하여 정렬을 완료합니다.
예시를 통해 팀 정렬 설명하기
1. 주어진 배열:
[5, 21, 7, 23, 19, 10, 17, 15, 1, 3, 2, 11, 6, 12, 14, 4, 13, 9, 8, 16, 18, 20]
2. 작은 배열 정렬 (삽입 정렬):
먼저 작은 크기의 배열을 정렬합니다. 일반적으로 팀 정렬에서는 RUN 크기(보통 32 또는 64)로 배열을 나누고, 각 부분 배열을 삽입 정렬로 정렬합니다.
예를 들어 RUN = 8 인 경우, 부분 배열을 다음과 같이 나눕니다:
- [5, 21, 7, 23, 19, 10, 17, 15]
- [1, 3, 2, 11, 6, 12, 14, 4]
- [13, 9, 8, 16, 18, 20]
각 부분 배열을 삽입 정렬로 정렬합니다:
- [5, 7, 10, 15, 17, 19, 21, 23]
- [1, 2, 3, 4, 6, 11, 12, 14]
- [8, 9, 13, 16, 18, 20]
3. 병합 단계:
작은 배열들을 순차적으로 병합합니다. 이 과정은 병합 정렬의 병합 과정과 유사합니다.
첫 번째 병합 단계:
- 병합 [5, 7, 10, 15, 17, 19, 21, 23] 와 [1, 2, 3, 4, 6, 11, 12, 14]:
- [1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 17, 19, 21, 23]
두 번째 병합 단계:
- 병합 [1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, 15, 17, 19, 21, 23] 와 [8, 9, 13, 16, 18, 20]:
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23]
결과:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23]
import java.util.Arrays;
public class TimSort {
private static final int RUN = 32;
public static void insertionSort(int[] arr, int left, int right) {
for (int i = left + 1; i <= right; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= left && arr[j] > temp) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
public static void merge(int[] arr, int l, int m, int r) {
int len1 = m - l + 1, len2 = r - m;
int[] left = new int[len1];
int[] right = new int[len2];
System.arraycopy(arr, l, left, 0, len1);
System.arraycopy(arr, m + 1, right, 0, len2);
int i = 0, j = 0, k = l;
while (i < len1 && j < len2) {
if (left[i] <= right[j]) {
arr[k] = left[i];
i++;
} else {
arr[k] = right[j];
j++;
}
k++;
}
while (i < len1) {
arr[k] = left[i];
k++;
i++;
}
while (j < len2) {
arr[k] = right[j];
k++;
j++;
}
}
public static void timSort(int[] arr, int n) {
for (int i = 0; i < n; i += RUN) {
insertionSort(arr, i, Math.min((i + 31), (n - 1)));
}
for (int size = RUN; size < n; size = 2 * size) {
for (int left = 0; left < n; left += 2 * size) {
int mid = left + size - 1;
int right = Math.min((left + 2 * size - 1), (n - 1));
if (mid < right) {
merge(arr, left, mid, right);
}
}
}
}
public static void printArray(int[] arr, int n) {
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = {5, 21, 7, 23, 19, 10, 17, 15, 1, 3, 2, 11, 6, 12, 14, 4, 13, 9, 8, 16, 18, 20};
int n = arr.length;
System.out.println("Given Array is");
printArray(arr, n);
timSort(arr, n);
System.out.println("After Sorting Array is");
printArray(arr, n);
}
}