병합 정렬의 기본 개념

1. 배열을 반으로 쪼갠다

2. 반으로 쪼갠 배열을 각각 또 반으로 쪼갠다.

3. 같은 방법으로 더 쪼갤 수 없을 만큼 쪼갠다

4. 쪼갠 배열을 순서에 맞춰 합친다

 

> 함수가 두 가지 필요하다. 배열을 반으로 나누는 함수, 그리고 그 나누어진 배열을 순서대로 맞추는 함수

void merge(int left, int right, int* arr){
	int mid = (left + right) /2;
    int right_first = mid + 1;
    int left_first = left;
    int temp_idx = left;
    int* temp[1000001];

    // 두 배열을 반으로 나누어 정렬 한다.
    while(left_first <= mid && right_first <= right){
    	// 왼쪽부터 순서대로 더 작은 값을 배치한다.
    	if(arr[left_first] <= arr[right_first]){
		temp[temp_idx++] = arr[left_first++];
        }else{
		temp[temp_idx++] = arr[right_first++];
        }
    }

    // 배치하면서 늘어난 left_first 인덱스가 mid값을 넘어선 경우
    if(left_first > mid){
    	// mid값 이후의 index를 temp에 넣어준다.
    	while(right_first <= right){
        	temp[temp_idx++] = arr[right_first++];
        }
    // 배치하면서 늘어난 left_first 인덱스가 mid값을 넘어서지 않은 경우
    }else{
    	// mid 값 이전의 index를 temp에 넣어준다.
    	while(left_first <= mid){
        	temp[temp_idx++] = arr[left_first++];
        }
    }
    
    // 배치한 temp값의 원소를 arr에 넣는다.
    while(left <= right){
    	arr[left] = temp[left];
        left++;
    }
}

// 계속 반으로 나누는 함수
void merge_sort(int left, int right, int* arr){
    int mid = (left + right ) / 2;
	
    if(left >= right) return;
    
    merge_sort(left, mid, arr);
    merge_sort(mid+1, right, arr);
    merge(left, right, arr);
}

 

기본 개념만 숙지해두고 이후는 코드를 보면서 이해하는게 편하다.

  • merge 함수에는 반으로 잘린 인덱스들이 들어온다.
    • 계속 반으로 나누다보면 결국 left인덱스와 right 인덱스 차이가 1만 나는 인덱스가 들어올것이다
    • merge에서 둘중 더 작은것을 왼쪽으로 보낸다(정렬이 하나 완성됐다)
    • 재귀가 하나 끝나고 밖으로 나와보면 완성된 두개의 배열을 맞이하게 된다.
    • 이 배열은 각각 정렬된상태여서 같은 방법을 적용시키면 더욱 길어진 정렬된 배열을 가질 수 있다.
    • 차근차근 이렇게 정렬시키다보면 결국 O(NlogN)의 시간복잡도를 보장할 수 있다.

'IT > 알고리즘' 카테고리의 다른 글

카운팅 정렬  (0) 2023.04.30
다익스트라 알고리즘  (0) 2023.04.28
함수의 점근적 분석법  (0) 2023.04.28
패스트캠퍼스 Java 코딩테스트 강의 1주차  (0) 2023.04.22
DFS / BFS  (0) 2022.12.02