합병 정렬
function merge(left_arr, right_arr) {
let result = [];
let [i, j] = [0, 0];
while (i < left_arr.length && j < right_arr.length) {
if (left_arr[i] < right_arr[j]) {
result.push(left_arr[i]);
i++;
} else {
result.push(right_arr[j]);
j++;
}
}
while (i < left_arr.length) {
result.push(left_arr[i]);
i++;
}
while (j < right_arr.length) {
result.push(right_arr[j]);
j++;
}
return result;
}
function merge_sort(arr) {
if (arr.length <= 1) return arr;
let mid_idx = Math.floor(arr.length / 2);
let left_arr = merge_sort(arr.slice(0, mid_idx));
let right_arr = merge_sort(arr.slice(mid_idx));
return merge(left_arr, right_arr);
}
let arr = [3, 6, 13, 4, 33, 12, 35, 87, 6, 64];
const result = merge_sort(arr);
console.log(result);
- 입력(배열) 두개를 받을 함수를 선언하며, 마지막에 결과값을 넣어서 반환할 빈 배열을 하나 만든다.
- 각 입력의 가장 작은 값부터 시작한다.
- 아직 살펴보지 않은 값이 있다면,
- 첫번째 배열에 있는 값이 두번째 배열에 있는 값보다 작다면, 결과값에 push 하고 다음순서를 밟는다.
- 만약 두번째 배열에 있는 값이 더 크다면, 두번째 배열을 결과값에 push 하고 두번째 배열의 다음 값을 살펴본다.
- 배열 하나를 완료하면 다른 배열은 그대로 넣어준다. (전 단계에서 이미 정렬되어 있을 것이다.)
시간 복잡도: O(n log n)
- 최악, 평균, 최선 모두 같은 시간 복잡도를 가진다.
- 입력값이 무엇이든 똑같이 최소의 엘리먼트를 가지는 배열로 나눈뒤 합하면서 정렬을 수행하기 때문이다.
- 시간 복잡도에 log n이 들어가는 이유는,
- 아래와 같이 밑이 2고 지수가 요소의 개수를 가지는 log의 값만큼 분할이 일어나기 때문이다.
- 아래와 같이 밑이 2고 지수가 요소의 개수를 가지는 log의 값만큼 분할이 일어나기 때문이다.
- 시간 복잡도에 n이 들어가는 이유는,
- 합병할때 n번의 합병을 거치기 때문이다.
- [1,3] 과 [2,4]의 두 배열을 합병한다고 해보자.
- 1과 2를 비교하여 result에 1을 push 하므로 result = [1]
- 3과 2를 비교하여 result에 2를 push 하므로 result = [1,2]
- 3과 4를 비교하여 result에 3을 push 하므로 result = [1,2,3]
- 마지막으로 4를 push하여 result = [1,2,3,4] 가 된다.
- 위 그림으로 살펴보자면 3의 단계에서 아래에서 위로 합병하는 경우를 생각하면 된다.
공간 복잡도: O(n)
- 배열이 길어질수록 분할하면서 생기는 sub배열들을 저장할 공간이 더 필요하므로 공간 복잡도는 크다.
'ALGORITHM > 정렬' 카테고리의 다른 글
Algorithm / 정렬 / Radix Sort (기수 정렬) (0) | 2022.08.31 |
---|---|
Algorithm / 정렬 / Quick Sort (퀵 정렬) (0) | 2022.08.31 |
Algorithm / 정렬 / Insertion Sort (삽입 정렬) (0) | 2022.08.18 |
Algorithm / 정렬 / Selection Sort (선택 정렬) (0) | 2022.08.17 |