개발 공부/알고리즘
[정렬 알고리즘] #5. 합병 정렬 (Merge Sort)
짹뚜
2022. 7. 11. 20:40
합병 정렬
분할 정복 알고리즘 중 하나이고 안정 정렬에 속하는 정렬 알고리즘이다.
알고리즘
합병 정렬은 다음과 같이 진행된다.
- Divide: 입력으로 받은 배열을 같은 크기의 2개의 배열로 길이가 1이 될 때까지 나눈다. (배열의 길이가 1일 때 배열이 정렬이 된 상태라고 본다.)
- Conquer: 2개의 정렬된 배열을 하나의 배열로 정렬을 하면서 합친다.
- 입력으로 받은 배열을 배열의 길이가 1개가 될 때까지 절반으로 나눠준다.
- 2개의 정렬된 배열을 서로 인덱스 0부터 비교하면서 더 작은 값을 또 다른 배열에 넣어준다.
- 2개의 배열 중 하나의 배열에서 모든 값을 새로운 배열에 넣을 때까지 반복한다.
- 만약 하나의 배열의 값들을 모두 넣어주면 남은 배열의 값들은 새로운 배열에 push 한다.
- 나눠진 모든 배열들이 합쳐질 때까지 반복한다.
// 자바스크립트 코드
const merge = (leftArr, rightArr) => {
const sortedArr = [];
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < leftArr.length && rightIndex < rightArr.length) {
if (leftArr[leftIndex] <= rightArr[rightIndex]) {
sortedArr.push(leftArr[leftIndex++]);
} else {
sortedArr.push(rightArr[rightIndex++]);
}
}
return [
...sortedArr,
...leftArr.slice(leftIndex),
...rightArr.slice(rightIndex),
];
};
const mergeSort = (arr) => {
if (arr.length === 1) return arr;
const mid = Math.ceil(arr.length / 2);
const leftArr = arr.slice(0, mid);
const rightArr = arr.slice(mid);
return merge(mergeSort(leftArr), mergeSort(rightArr));
};
특징
- 입력 데이터가 무엇이든 정렬되는 속도는 동일하다.
- 합병을 할 때는 O(log n)의 시간복잡도를 가지고 각 합병 단계에서 2개의 배열을 비교할 때는 O(n)의 시간복잡도를 가진다.
- 따라서, O(n log n) 의 시간 복잡도를 가진다.