본문 바로가기
알고리즘

Divide and Conquer

by 메릴린 2022. 12. 9.
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(\cfrac{n}{2})+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

댓글