
- Merge Sort (합병정렬) 은 정렬알고리즘 중 가장 빠른 알고리즘 중 하나이다.
→ O(n logn)- 합병 정렬의 기본 아이디어는 <divide and conquer> 이다.
- 먼저 나눈 후, 이후에 병합한다.
이렇게 정렬되지 않은 카드가 있다고 가정하자.

public func mergeSort<Element>(_ array: [Element]) -> [Element] where Element: Comparable {
let middle = array.count / 2
let left = Array(array[..<middle])
let right = Array(array[middle...])
// ...
}
public func mergeSort<Element>(_ array: [Element]) -> [Element] where Element: Comparable {
// 1.
guard array.count > 1 else { return array }
let middle = array.count / 2
// 2.
let left = mergeSort(Array(array[..<middle]))
let right = mergeSort(Array(array[middle...]))
// ...
}
재귀의 탈출 조건
→ 배열이 오직 하나의 원소만 가질 때 재귀 탈출함
쪼갠 배열을 다시 쪼개기 위해 mergeSort 자신을 반복해서 호출함. 이건 언제 멈춘다? → 요소가 하나만 남았을때!!
private func merge<Element>(_ left: [Element], _ right: [Element]) -> [Element] where Element: Comparable {
// 1. 진행사항을 따라가기 위한 인덱스 변수 선언 및 초기화
// 처음부터 비교를 시작한다.
var leftIndex = 0
var rightIndex = 0
// 2. 병합된 배열
var result: [Element] = []
// 3. leftIndex가 left배열의 끝에 도달하지 않았고,
// rightIndex가 right 배열의 끝에 도달하지 않았을 때
**while leftIndex < left.count && rightIndex < right.count {**
// 처음부터 시작해서 계속 왼, 오 요소를 비교한다
let leftElement = left[leftIndex]
let rightElement = right[rightIndex]
// 4. 두 배열의 각 요소를 비교했을 때 더 작은게 result로 들어간다.
// 같으면 둘 다 들어간다.
if leftElement < rightElement {
result.append(leftElement)
leftIndex += 1
} else if leftElement > rightElement {
result.append(rightElement)
rightIndex += 1
} else { // 같으면 둘 다 추가하고 모두 index 증가한다.
result.append(leftElement)
leftIndex += 1
result.append(rightElement)
rightIndex += 1
}
}
// 여기서 3번 while 문이 종료되면, 어느 한 쪽 배열의 요소는 모두 처리된 상태이다
// -> 일단 적어도 하나는 index가 배열의 끝에 도달했기 때문에 while 문을 탈출한 것일 테니까
//5. 나머지 요소가 남아있는 배열이 있을 수 있으므로, 남은 요소들을 모두 result 에 추가하는 과정
// leftIdnex가 아직 left 배열의 끝에 도달하지 않았다면, 그 나머지를 result에 추가
if leftIndex < left.count {
result.append(contentsOf: left[leftIndex...])
}
// 오른쪽도 마찬가지로 끝나지 않고 남은 요소들을 result에 추가
if rightIndex < right.count {
result.append(contentsOf: right[rightIndex...])
}
return result
}
public func mergeSort<Element>(_ array: [Element]) -> [Element] where Element: Comparable {
guard array.count > 1 else { return array }
let middle = array.count / 2
let left = mergeSort(Array(array[..<middle]))
let right = mergeSort(Array(array[middle...]))
return merge(left, right)
}
시간복잡도
공간복잡도
(In-Place 알고리즘 > 추가적인 메모리 공간 거의 사용하지 않고 직접 수정해 문제를 해결하는 알고리즘)!