/**
Merge Sort(합병정렬)
- 배열을 절반으로 계속 분할해서 길이가 1이 되도록 만들고, 인접한 부분끼리 정렬하면서 합병하는 방식 (Divide & Conquer)
- 장점
- 동일한 값의 경우, 들어온 순서대로 정렬되므로 Stable Sort 이다.
- 최악의 경우에도 시간 복잡도 = O(nlogn)
- 단점
- 추가적인 배열이 필요하므로 in-place Sort가 아니기 때문에 메모리 사용량이 많다.
- 원본 배열에 추가적인 배열의 값을 복사하는 과정이 많은 시간을 소비하기 때문에 데이터가 많을 경우 시간이 많이 소요된다.
*/
public class MergeSort {
public static void mergeSort(int[] arr, int[] tmp, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, tmp, left, mid);
mergeSort(arr, tmp, mid + 1, right);
merge(arr,tmp,left,right,mid);
}
}
public static void merge(int[] arr, int[] tmp, int left, int right, int mid) {
// 반으로 나눈 배열 중, 왼쪽 배열에서 움직일 포인터로 초깃값은 가장 앞 인덱스인 left
int p = left;
// 오른쪽 배열에서 움직일 포인터로 초깃값은 가장 앞 인덱스인 mid+1
int q =mid +1;
int idx = p;
// 합병할 데이터가 남아있는 경우
while (p <= mid || q <= right) {
// 둘 다 남아있는 경우, 서로 비교하면서 포인터 값들 증가
if (p <= mid && q <= right) {
if (arr[p] <= arr[q]) {
tmp[idx++] = arr[p++];
} else {
tmp[idx++] = arr[q++];
}
}
// 둘 다 비교한 후, 한쪽이 끝에 도달한 경우
// 남아있는 데이터를 처리
if (p <= mid) {
tmp[idx++] = arr[p++];
}
if (q <= right) {
tmp[idx++] = arr[q++];
}
// 원래 배열에 정렬된 데이터를 넣기
for (int i = left; i <= right; i++) {
arr[i] = tmp[i];
}
}
}
}
찾아보니 정렬을 재귀적으로 구현하는게 안좋다고 한다. 재귀적으로 구현하지 않는 방식도 있으니 필요하면 찾아볼 것
'알고리즘 > 개념' 카테고리의 다른 글
Radix Sort (기수정렬) (0) | 2022.04.30 |
---|---|
Heap Sort (힙 정렬) (0) | 2022.04.30 |
빅오 표기별 커버 가능한 크기 (0) | 2022.04.26 |
이진 탐색 트리 (BST,Binary Search Tree) (0) | 2022.04.25 |
트리 (Tree), 이진 트리 (Binary Tree) (0) | 2022.04.24 |
댓글