2024. 9. 13. 12:19ㆍ알고리즘
배열을 오름차순 혹은 내림차순으로 정렬하는 알고리즘 중 하나이다. 버블 정렬 알고리즘보다 복잡하지만, 속도가 빠르다는 것이 장점이다.
1. 하나의 배열이 있을때 길이가 1이 될때까지 /2로 게속 쪼개어 준다.
2. 쪼개진 배열을 2개씩 비교 후 병합한다.
이론적으론 쉽지만 재귀함수를 써야하기 때문에 구현하기는 생각보다 어렵다. 밑에는 병합 정렬의 로직을 표현한 것이다.
void Merge(int a[],int left, int mid , int right)
{
}
void Divide(int a[], int left, int right)
{
}
우선 2가지의 기능을 하는 함수가 필요하다. 배열을 쪼개어줄 분할 함수와 그걸 다시 합치면서 비교해줄 병합 함수 두가지이다.
void Divide(int a[], int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
Divide(a, left, mid);
Divide(a, mid + 1, right);
Merge(a, left, mid, right);
}
}
배열의 길이가 1이 될때까지 나누어야 하기 때문에 조건을 left<right 걸어둔다. 이후 중간 지점인 mid를 구해 재귀함수를 돌려준다.
배열이 전부 나누어졌다면 더이상 재귀함수는 반복하지 않고 Merge함수 부분으로 넘어가게 된다. 그렇기 때문에 분할 후 병합하는 함수를 통해 함수가 합쳐지게 된다.
void Merge(int a[], int left, int mid, int right)
{
int temp[100];
int i = left;
int j = mid + 1;
int k = 0;
}
Merge 함수 부분이다 우선 정렬된 인덱스를 잠시 넣어둘 temp를 만들어준다
i 는 비교가될 두 배열중의 왼쪽을, j는 오른쪽을 맡는다.
while (i <= mid && j <= right)
{
if (a[i] <= a[j])
{
temp[k] = a[i];
i++;
k++;
}
else if (a[i] > a[j])
{
temp[k] = a[j];
j++;
k++;
}
}
i와 j의 인덱스값을 비교해 더 작은쪽을 temp에 담아주는 방식이다. 그래서 k는 temp의 위치 인덱스이다.
while (i <= mid)
{
temp[k] = a[i];
i++;
k++;
}
while (j <= right)
{
temp[k] = a[j];
j++;
k++;
}
만약 두 배열중 하나가 전부 끝낫다면 다른하나를 전부 담아주는 while문을 작성한다.
k--;
while (k >= 0)
{
a[left + k] = temp[k];
k--;
}
마지막으로 정렬된 배열을 실제 a배열에 담아준다. 중요한 점은 현재k가 이미 배열의 길이를 넘어섰기 때문에 한번 빼주어야 한다.
#include <iostream>
using namespace std;
void Merge(int a[], int left, int mid, int right)
{
int temp[100];
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right)
{
if (a[i] <= a[j])
{
temp[k] = a[i];
i++;
k++;
}
else if (a[i] > a[j])
{
temp[k] = a[j];
j++;
k++;
}
}
while (i <= mid)
{
temp[k] = a[i];
i++;
k++;
}
while (j <= right)
{
temp[k] = a[j];
j++;
k++;
}
k--;
while (k >= 0)
{
a[left + k] = temp[k];
k--;
}
}
void Divide(int a[], int left, int right)
{
if (left < right)
{
int mid = (left + right) / 2;
Divide(a, left, mid);
Divide(a, mid + 1, right);
Merge(a, left, mid, right);
}
}
int main()
{
int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
int arrSize = 10;
for (int i = 0; i < arrSize; i++)
{
cout << arr[i] << ", ";
}
cout << "\n" << endl;
Divide(arr, 0, arrSize - 1);
for (int i = 0; i < arrSize; i++)
{
cout << arr[i] << ", ";
}
}
'알고리즘' 카테고리의 다른 글
퀵 정렬(quick sort) c++ (0) | 2024.09.13 |
---|---|
버블 정렬 (bubble sort) c++ (0) | 2024.09.10 |