반응형
merge sort 개념
- 퀵소트처럼 대표적인 divide & conquer 알고리즘 중 하나.
- merge sort는 퀵소트와 비교했을 때, 안정적으로 nlogn의 시간복잡도를 내는 알고리즘이다.
- 퀵소트, 힙정렬에 비해서 메모리사용량이 더 많다.
- 평균적으로는 퀵소트보다 더 오래걸린다.
- 따라서 특수한 케이스가 아니라면 머지소트보다는 퀵소트를 더 많이 사용한다.
머지소트개념은 나누어서 정리해서 합친다는 개념이다.
여기서는 더 이상의 개념설명은 하지 않겠다.
merge sort 구현
머지소트를 구현함에 있어서 나는 두가지 방법으로 접근했다.(결과는 같다)
1. 직관적, 순차적인 접근 : divide를 최소단위가 될 때 까지 시행하고서 conquer하는 접근
2. 재귀적인 접근 : divide를 해서 두 개의 part가 생기면 각각을 conquer. --> conquer안에서는 다시 divide 와 conquer를 실행한다.
1번 코드는 아래와 같다.
#include <iostream>
#define MAX 10
using namespace std;
void MergeSort(int arr[], int l, int r);
void Conquer(int arr[], const int l, const int r);
void Divide(int arr[], int l, int r);
int tmp[MAX];
void Divide(int arr[], int l, int r)
{
if (l < r)
{
int m = (r + l) / 2;
Conquer(arr, l, m);
Conquer(arr, m + 1, r);
}
}
void Conquer(int arr[], const int l, const int r) // 이거 아닌거같음...
{
Divide(arr, l, r); // divide 명령을 하면 하위 part들은 모두 정렬되서 올라온다고 생각하면 된다.
int m = (l + r) / 2;
int i = l, ll = l;
int j = m+1;
// 두 part중에 모두 비어진 part가 하나라도 없는경우
while (i <= m && j <= r)
{
if (arr[i] < arr[j])
tmp[ll++] = arr[i++];
else
tmp[ll++] = arr[j++];
}
//두 part중 하나가 다 비어진경우
while (i <= m)
tmp[ll++] = arr[i++];
while (j <= r)
tmp[ll++] = arr[j++];
//tmp를 다시 arr에 복사한다.
for (int i = l; i <= r; i++)
{
arr[i] = tmp[i];
}
}
void MergeSort(int arr[], int l, int r)
{
Conquer(arr, l, r);
}
int main()
{
int arr[MAX] = { 3,5,6,1,2,4,0,9,7,8 };
MergeSort(arr, 0, MAX-1);
for (int i = 0; i < MAX; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}
2번 코드는 아래와 같다.
#include <iostream>
#define MAX 10
using namespace std;
void MergeSort(int arr[], int l, int r);
void Conquer(int arr[], const int l, const int r);
void Divide(int arr[], int l, int r);
int tmp[MAX];
void Divide(int arr[], int l, int r)
{
if (l < r)
{
int m = (l + r) / 2;
Divide(arr, l, m);
Divide(arr, m + 1, r);
Conquer(arr, l, r);
}
}
void Conquer(int arr[], const int l, const int r)
{
int m = (l + r) / 2;
int i = l, ll = l;
int j = m + 1;
// 두 part중에 모두 비어진 part가 하나라도 없는경우
while (i <= m && j <= r)
{
if (arr[i] < arr[j])
tmp[ll++] = arr[i++];
else
tmp[ll++] = arr[j++];
}
//두 part중 하나가 다 비어진경우
while (i <= m)
tmp[ll++] = arr[i++];
while (j <= r)
tmp[ll++] = arr[j++];
//tmp를 다시 arr에 복사한다.
for (int i = l; i <= r; i++)
{
arr[i] = tmp[i];
}
}
void MergeSort(int arr[], int l, int r)
{
Divide(arr, l, r);
}
int main()
{
int arr[MAX] = { 3,5,6,1,2,4,0,9,7,8 };
MergeSort(arr, 0, MAX - 1);
for (int i = 0; i < MAX; i++)
{
cout << arr[i] << ' ';
}
cout << endl;
return 0;
}
반응형
'Programming > 알고리즘' 카테고리의 다른 글
[퀵소트 구현] 퀵소트 구현, 최악의 케이스 직접 확인 (0) | 2020.08.06 |
---|---|
[백준 경로찾기] DFS 문제, 2차원 벡터 활용 (0) | 2020.03.14 |
[다익스트라] 개념 정리 (0) | 2020.03.14 |
[백준 ACM craft] 위상정렬 문제 (0) | 2020.03.08 |
[백준 A/B] double 출력 자릿수 문제 (0) | 2020.03.03 |