void merge(vector<int>& arr, const int& start, const int& end) {
int i = start;
int mid = (start + end) / 2;
int j = mid + 1;
vector<int> temp;
while (i <= mid && j <= end) {
if (arr[i] < arr[j])
temp.emplace_back(arr[i++]);
else
temp.emplace_back(arr[j++]);
}
while (i <= mid) temp.emplace_back(arr[i++]);
while (j <= end) temp.emplace_back(arr[j++]);
int k = 0;
for (int idx = start; idx <= end; ++idx)
arr[idx] = temp[k++];
}
void merge_sort(vector<int>& arr, const int& start, const int& end) {
if (start >= end) return;
int mid = (start + end) / 2;
merge_sort(arr, start, mid);
merge_sort(arr, mid + 1, end);
merge(arr, start, end);
}
먼저 전체 배열 길이의 절반에 해당되는 인덱스 mid를 구하고 start~mid, mid+1~end 2개의 구간으로 나누어 재귀적으로 분할한 뒤에 합친다.
공간 복잡도는 O(N), 시간 복잡도는 O(NlogN)이다.
Quick Sort(퀵 정렬)
병합 정렬과 마찬가지로 분할 정복 알고리즘이지만 분할이 균일하게 이루어지지 않는다.
pivot값을 기준으로 대략적인 정렬이 이뤄진 후에 pivot값의 위치가 확정되며 그 위치를 기준으로 분할된다.
// 원래 알고있는 코드
void quick_sort(vector<int>& arr, const int& start, const int& end) {
if (start >= end) return;
int pivot = arr[start];
int left = start + 1;
int right = end;
while (left < right) {
while (pivot >= arr[left]) left++;
while (pivot < arr[right]) right--;
if (left < right) swap(arr[left], arr[right]);
}
swap(pivot, arr[right]);
quick_sort(arr, start, right -1);
quick_sort(arr, right + 1, end);
}
// 강의에서 제시한 코드
int partition(vector<int>& arr, const int& start, const int& end) {
int pivot = arr[start];
int i = start - 1;
for (int j = start; j < end; ++j) {
if (arr[j] < pivot) {
++i;
swap(arr[i], arr[j]);
}
}
swap(arr[i+1], arr[end]);
return i+1;
}
void quick_sort(vector<int>& arr, const int& start, const int& end) {
if (start >= end) return;
int p = partition(arr, start, end);
quick_sort(arr, start, p-1);
quick_sort(arr, p+1, end);
}