배열을 계속 반으로 나눠서 단일 배열로 분할한 뒤, 다시 정렬하면서 병합한다. => 분할 정복 알고리즘
ex. n개의 element가 담긴 배열이 있으면, n개의 단일 요소 배열이 될 때까지 계속 반으로 분할하고 다시 정렬하면서 병합시킨다.
대부분의 합병 정렬 구현 시 재귀
를 사용한다.
합병 정렬 과정 애니메이션으로 보기
https://visualgo.net/en/sorting?slide=1-1
let answer = [];
i
= 0, j
= 0)[1,10,50], [2,14,99,100]
i j
[1,10,50], [2,14,99,100]
1->3->5 2->4
answer = [1,2,10,50]
[1,10,50], [2,14,99,100]
(전부 넣기)
answer = [1,2,10,50,99,100]
// Merges two already sorted arrays
function merge(arr1, arr2){
let results = [];
let i = 0;
let j = 0;
while(i < arr1.length && j < arr2.length){
if(arr2[j] > arr1[i]){
results.push(arr1[i]);
i++;
} else {
results.push(arr2[j])
j++;
}
}
// 한 배열의 끝에 도달한 경우
while(i < arr1.length) {
results.push(arr1[i])
i++;
}
while(j < arr2.length) {
results.push(arr2[j])
j++;
}
return results;
}
merge([100,200], [1,2,3,5,6])
point : 재귀를 이용한다.
ex) [10,24,76,23]
step1. left = [10,24] (mergeSort)
step2. left = [10] (mergeSort)
step3. right = [24] (mergeSort)
step4. [10,24] (merge)
step5. right = [76,23] (mergeSort)
step6. left = [76] (mergeSort)
step7. right = [23] (mergeSort)
step8. [23, 76] (merge)
step9. [10,23,24,76] (merge) 끝!
코드
// Merge function
function merge(arr1, arr2){
let results = [];
let i = 0;
let j = 0;
while(i < arr1.length && j < arr2.length){
if(arr2[j] > arr1[i]){
results.push(arr1[i]);
i++;
} else {
results.push(arr2[j])
j++;
}
}
// 한 배열의 끝에 도달한 경우
while(i < arr1.length) {
results.push(arr1[i])
i++;
}
while(j < arr2.length) {
results.push(arr2[j])
j++;
}
return results;
}
// Recrusive Merge Sort
function mergeSort(arr){
if(arr.length <= 1) return arr;
let mid = Math.floor(arr.length/2);
let left = mergeSort(arr.slice(0,mid));
let right = mergeSort(arr.slice(mid));
return merge(left, right);
}
mergeSort([10,24,76,73])
시간 복잡도 : O(n log n)
- 평균,최고,최악의 케이스 모두 동일.
- 예외 케이스가 없고, 어떤 형태의 데이터가 주어지든 동일한 시간 복잡도를 보인다는 장점이 있음.
n개의 element가 담긴 배열이 주어질 때, 절반으로 계속 나눠서 단일 배열이 되게 하려면 총 log n
만큼의 시행이 필요하다.
ex. [1,2,3,4,5,6,7,8]
[1,2,3,4] [5,6,7,8]
[1,2] [3,4] [5,6] [7,8]
[1][2] [3][4] [5][6] [7][8]
=> 8개로 나누기 위해 3번의 실행이 필요. (반대로 2^3 = 8)
각 분할마다 합병할 때 n
번씩 비교한다.
따라서 n x log n = n log n 이므로 시간 복잡도가 n log n
이 된다.
공간 복잡도 : O(n)
배열이 클수록 메모리에 더 많은 배열을 저장해야 한다.
공간 복잡도 측면에서는 버블 정렬, 선택 정렬, 삽입 정렬 보다 더 많은 공간을 차지한다.