728x90
Divide and Conquer
크기 N짜리 문제에 대해 top-down 방식으로 하여 "재귀적"으로 문제를 푸는 알고리즘
- 크기 N짜리 문제를 N보다 크기가 작은 subproblems으로 나눈다 (Divide)
- subproblems를 기존의 방식으로 풀어낸다(recursive). (Conquer)
- 이때 subproblems가 크기 N에 대해 "모두" 고려해야한다.
Merge Sort
N개의 크기를 가지는 array를 nondecreasing하게 정렬하기
크기 N인 array에 대해 N/2 인 subarray로 나누어 문제를 해결
T(n)=2T(n2)+cn
- T(n) : 입력 크기가 n인 문제를 해결하는 데에 드는 비용
Base Step
가장 크기가 작은 입력데이터에 대한 결과를 고려해야 한다.
Merge Sort에서는 입력데이터가 하나인 경우이다. 입력데이터의 크기가 하나일 경우 Divide를 종료하고 Merge를 시작한다.
T(1)=1
Merge
입력으로 두 subarray가 들어오면 두 subarray를 각각 돌면서 nondecreasing으로 정렬되게 두 배열을 합친다.
이때 입력으로 들어온 subarray는 이미 nondecreasing 상태이다.
Time Complexity
Divide | Conquer | Combine |
---|---|---|
O(1) | 2T(n/2) | O(n) |
⇒ T(n)=O(nlogn)
Example Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int item_type;
int N;
item_type *buffer;
void print_array(item_type* A)
{
for(int i=0; i<N; i++)
{
printf("%d ",A[i]);
}
printf("\n");
}
void merge(item_type *A, int left, int mid, int right)
{
int i, i_left, i_right;
memcpy(buffer+left, A+left, sizeof(item_type)*(right-left+1));
i_left=left;
i_right=mid+1;
i=left;
while((i_left<=mid)&&(i_right<=right)){
if(buffer[i_left]<=buffer[i_right])
A[i++]=buffer[i_left++];
else A[i++]=buffer[i_right++];
}
while(i_left <= mid)
A[i++]=buffer[i_left++];
while(i_right <= right)
A[i++]=buffer[i_right++];
}
void merge_sort(item_type *A, int left, int right)
{
int mid;
if (left < right)
{
mid = (left+right)/2;
merge_sort(A, left, mid);
merge_sort(A, mid+1, right);
merge(A, left, mid, right);
}
}
int main(void)
{
item_type *A;
int i;
printf("Enter the size of array: ");
scanf("%d", &N);
buffer = (item_type*)malloc(sizeof(item_type)*N);
A = (item_type*)malloc(sizeof(item_type)*N);
printf("Enter the array A: ");
for(i=0; i<N; i++){
scanf("%d", &A[i]);
}
merge_sort(A, 0, N-1);
print_array(A);
free(A);
free(buffer);
return 0;
}
서강대학교 임인성 교수님 알고리즘 수업을 기반으로 작성한 문서입니다
728x90
반응형
'알고리즘' 카테고리의 다른 글
Dynamic Programming (0) | 2022.12.09 |
---|---|
Greedy (0) | 2022.12.09 |
댓글