버블 정렬, 선택 정렬, 삽입 정렬
은 확장성이 좋지 않다. 예를 들어, 이러한 알고리즘으로 10만 개 정도 요소가 있는 배열을 정렬하려면 시간이 많이 걸린다.합병 정렬, 퀵 정렬, 지수 정렬
등의 알고리즘을 사용할 수 있다.병합 정렬은 1945년 컴퓨터공학자이자 수학자인 존 폰 노이만
에 의해 개발됐다. 분할 정복
알고리즘 중 하나다.
병합
과 정렬
을 조합한 알고리즘이다.- 빈 배열을 만들고 각 입력 배열에서 가장 작은 값들을 살펴본다.
- 첫번째 배열에 있는 i번째 요소를 두번째 배열의 j번째 요소와 비교한다.
- 만약 첫번째 배열의 요소가 더 작다면, 첫번째 배열의 요소를 나중에 반환할 배열에 push하고, 첫번째 배열의 다음 요소로 이동한다.
- 만약 첫번째 배열의 요소가 더 크다면, 두번째 배열의 요소를 나중에 반환할 배열에 push하고, 두번째 배열의 다음 값으로 이동한다.
- 위 과정을 반복하다가 하나의 배열을 소진하면, 다른 배열의 나머지 요소들을 모두 push한다.
function mergeArray(array1, array2) {
const result = [];
let i = 0;
let j = 0;
while (i < array1.length && j < array2.length) {
if (array1[i] < array2[j]) {
result.push(array1[i]);
i++;
} else {
result.push(array2[j]);
j++;
}
}
if (i === array1.length) return result.concat(array2.slice(j));
if (j === array2.length) return result.concat(array1.slice(i));
}
console.log(mergeSort([1, 3, 7, 9, 11], [2, 6, 10, 16, 17, 18, 19, 20]));
재귀형 코드이다.
function merge(array1, array2) {
const result = [];
let i = 0;
let j = 0;
while (i < array1.length && j < array2.length) {
if (array1[i] < array2[j]) {
result.push(array1[i]);
i++;
} else {
result.push(array2[j]);
j++;
}
}
if (i === array1.length) return result.concat(array2.slice(j));
if (j === array2.length) return result.concat(array1.slice(i));
}
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); // 정렬된 두 배열을 정렬하여 합쳐주는 헬퍼 함수 사용
}
console.log(mergeSort([10,24,76,73]));
log n
: n개의 요소를 지닌 배열을 1개 이하의 요소만 지닌 배열들로 나누기 위해서는 번의 과정이 필요하다. (ex 8개 요소를 지닌 배열을 1개 요소만 지닌 배열들로 나누려면, 8→4→2→1처럼 (=3) 번의 과정 필요) - 재귀n
: 최소단위로 나눈 배열들을 다시 합칠 때는 n 번의 비교를 해야한다. (위에서 merge함수)