메뉴
Merge Sort (합병 정렬)

2011. 2. 26. 20:15

알고리즘

Array를 반씩 쪼갠다.
한번 쪼개면 두개의 큰 덩어리가 나올 것이다.
이렇게 나온 덩어리를 또 다시 쪼갠다.
이렇게 덩어리를 계속 쪼개다 보면, 결국 한 개의 원소가 하나의 덩어리가 된다.

이 상태에서 다시 덩어리를 뭉치는데, 그냥 뭉치는 것이 아니라
각각의 원소를 비교해 가면서 원소를 차례로 배열한다.
이런 식으로 덩어리를 계속 뭉쳐가다 보면 원래의 Array가 정렬된다.
이것이 합병 정렬의 기본 아이디어다.



코드

#include <stdio.h>
#define LEN 9

void merge_sort(int num[],int start, int end); 
void merge(int num[], int start, int mid, int end);
void tracer(int num[],int len);

int main(void){
    
    int testArr[LEN] = {485,241,454,325,452,685,498,890,281};
    merge_sort(testArr, 0, LEN-1);
}

void merge_sort(int num[],int start, int end){ // Array를 두개의 덩어리로 나눔
    int median = (start + end)/2; // 중간값 설정
    if(start < end){ // 덩어리의 원소가 하나일 때까지
        merge_sort(num, start, median); 
        merge_sort(num, median+1, end); // 각각의 덩어리로 재귀함수 호출 
        merge(num, start, median, end); // 각각의 덩어리를 뭉치면서 정렬
    }
}

void merge(int num[], int start, int median, int end){
    int i,j,k,m,n;
    int tempArr[LEN]; // 임시로 데이터를 저장할 배열
    i = start; // 앞의 덩어리의 시작 Index
    j = median+1; // 뒤의 덩어리의 시작 Index
    k = start; // 임시 배열의 시작 Index

    while (i <= median && j <= end){
        tempArr[k++] = (num[i] > num [j]) ? num [j++] : num [i++];
        //작은 숫자를 찾아 임시 배열에 넣는다. 어느쪽 덩어리든 Index의 끝에 닿으면 빠져나온다.
    }
    
    // 아직 배열에 속하지 못한 부분들을 넣기 위한 부분
    m = (i > median) ? j : i; // 아직 원소가 남아있는 덩어리가 어디인지 파악
    n = (i > median) ? end : median; // 마찬가지로, for문의 끝 Index를 정하기 위함임

    for (; m<=n; m++){ // 앞에서 구한 m, n으로 배열에 속하지 못한 원소들을 채워넣음
        tempArr[k++] = num[m];
    }

    for (m=start; m<=end; m++){
        num[m] = tempArr[m]; // 임시 배열에서 원래 배열로 데이터 옮기기
    }
    printf("Merging: %d ~ %d & %d ~ %d\n",start,median,median+1,end);
    tracer(num,LEN);
}

void tracer(int num[],int len){
    int i;
    for(i=0;i<len;i++){
        printf("%d\t",num[i]);
    }
    printf("\n\n");
}



결과




분석

위에서 9개의 원소를 가진 배열의 인덱스를 각각 0 ~ 8 이라고 했을때,
다음과 같은 덩어리로 나뉘어진다.

(((0, 1), 2), (3, 4)), ((5, 6), (7, 8))

결과에서 표시하고 있는 것은 이렇게 나뉘어진 원소들의 Index와 병합한 이후의 Array라고 할 수 있다.