둠치킨
코딩하는 둠치킨
둠치킨

블로그 메뉴

  • 홈
  • 분류 전체보기 (217) N
    • BOJ (170) N
      • 스택 (14)
      • 큐 (5)
      • 덱 (4)
      • 그래프 (30)
      • 배열 (8)
      • 재귀 (12)
      • 브루트 포스 (2)
      • 그리디 알고리즘 (7)
      • 다이내믹 프로그래밍 (13) N
      • 백트래킹 (24)
      • 기하학 (4)
      • 트리 (4)
      • 구현 (14)
      • 수학 (3)
      • 맵 (1)
      • 다익스트라 (2)
      • 누적합 (4) N
    • 자료구조 (14)
      • 스택 (3)
      • 큐 (5)
      • 덱 (2)
      • 그래프 (1)
      • 트리 (1)
      • 힙 (1)
      • 정렬 (1)
    • C++ (11)
      • 모두의코드 (2)
      • Effective C++ (3)
      • C++ STL (6)
    • 컴파일러 (1)
    • OS (17)
    • 컴퓨터 구조 (2)
    • Unreal Engine 5 (2)

공지사항

전체 방문자
오늘
어제

인기 글

최근 글

태그

  • BFS
  • boj
  • Bruteforce
  • C
  • C++
  • C++ STL
  • Cache Memory
  • deadlock
  • DFS
  • Effective C++
  • java
  • Mutex
  • next_permutation
  • os
  • Process
  • rotate
  • semaphore
  • spin lock
  • STL
  • STL C++
hELLO · Designed By 정상우.
둠치킨

코딩하는 둠치킨

병합 정렬 (Merge Sort)
자료구조/정렬

병합 정렬 (Merge Sort)

2025. 6. 2. 19:14

병합 정렬이란?

병합 정렬(Merge Sort)은 분할 정복(Divide and Conquer) 전략을 사용하는 대표적인 정렬 알고리즘이다.
배열을 작게 쪼개서 정렬한 뒤, 다시 합치면서 전체를 정렬해나가는 방식이다.


핵심 개념 요약

Divide (분할)

  • 배열을 반으로 나눈다.
  • 더 이상 나눌 수 없을 때까지 계속 쪼갠다 (즉, 길이가 1이 될 때까지).

Conquer (정복)

  • 쪼개진 배열을 병합하며 정렬한다.
  • 두 개의 정렬된 배열을 하나의 정렬된 배열로 합친다

병합 정렬 흐름

예를 들어 배열이 아래와 같다고 해보자:

[21, 10, 12, 20, 25, 13, 15, 22]
 
 
 
 
그림처럼 병합 정렬은 이 배열을 계속 반으로 쪼개고, 마지막에는 정렬된 조각들을 차례로 병합한다:
  • 가장 아래에선 [21], [10] 같이 한 원소짜리 배열이 만들어짐
  • 그 다음 단계에선 [10, 21], [12, 20]처럼 병합하며 정렬된 두 원소 배열이 생김
  • 마지막엔 전체가 정렬된 하나의 배열로 완성됨

병합(Combine) 과정 자세히 보기

두 정렬된 배열을 병합하는 핵심 로직은 다음과 같다:

  • 두 배열 각각 앞에서부터 비교
  • 더 작은 값을 먼저 새로운 배열(sorted)에 추가
  • 한쪽이 먼저 다 끝나면, 남은 쪽은 그대로 복사

아래 그림은 이 병합 과정을 실제로 시각화한 것이다:

  • 왼쪽: [10, 12, 20, 21]
  • 오른쪽: [13, 15, 22, 25]
  • 결과: [10, 12, 13, 15, 20, 21, 22, 25]

코드

void merge(int p, int q, int r) {
    int i = p, j = q + 1, t = 0;
    
    // 두 포인터를 비교하며 tmp에 복사
    while (i <= q && j <= r) {
        if (A[i] <= A[j]) tmp[t++] = A[i++];
        else tmp[t++] = A[j++];
    }
    
    // 남은 값들 마저 복사
    while (i <= q) tmp[t++] = A[i++];
    while (j <= r) tmp[t++] = A[j++];

    // tmp → A 복사
    i = p; t = 0;
    while (i <= r) {
        A[i++] = tmp[t++];
    }
}

void merge_sort(int p, int r) {
    if (p < r) {
        int q = (p + r) / 2;
        merge_sort(p, q);        // 왼쪽 정렬
        merge_sort(q + 1, r);    // 오른쪽 정렬
        merge(p, q, r);          // 병합
    }
}

시간 복잡도

케이스복잡도
최선 O(N log N)
평균 O(N log N)
최악 O(N log N)
 
  • 항상 안정적인 성능을 보장함
  • 데이터가 이미 정렬되어 있어도 시간 복잡도는 변하지 않음

안정 정렬

  • 안정 정렬이란? 값이 같은 원소들의 원래 순서가 유지되는 정렬
  • 병합 정렬에서는 같은 값이 있을 경우, 먼저 등장한 값을 먼저 복사하기 때문에 안정성이 유지됨
  • 예: (A, 3)와 (B, 3)이 있다면 정렬 후에도 A가 B보다 앞에 옴

참고: 병합 정렬이 활용된 예제

백준 24060번 : 병합 정렬을 수행하면서 "배열에 저장되는 순간"을 추적하는 문제

저작자표시 (새창열림)
    둠치킨
    둠치킨
    코딩 공부를 위한 코딩 블로그 기록 일기

    티스토리툴바