합병 정렬 (Merge Sort)

2021. 4. 30. 18:45·SW개발/알고리즘
반응형

합병 정렬 (Merge Sort)

  • 입력이 2개의 부분문제로 분할되고, 부분문제의 크기가 1/2로 감소하는 분할 정복 알고리즘
  • 연결 리스트에 있는 데이터를 정렬할 때 퀵 정렬이나 힙 정렬보다 훨씬 효율적이라고 한다.
    MergeSort(int arr[], int p, int q)
    {
      if (p < q)
      {
        int k = (p + q) / 2;
        MergeSort(arr, p, k);
        MergeSort(arr, k + 1, q);
        arr[p] ~ arr[k]와 arr[k + 1] ~ arr[q]를 합병한다.
      }
    }
  • pseudo code

시간 복잡도

  • 분할하는 부분
    • 배열의 중간 인덱스 계산과 재귀 호출 2번으로 O(1) 시간이 걸린다.
  • 합병하는 부분
    • 두 정렬된 배열 A, B의 크기가 각각 n과 m이고 이를 합병하여 새로운 배열 C를 만드는 부분
      • (n + m - 1)번의 비교를 통해 배열 C를 채우므로 시간 복잡도는 O(n + m)이다.
    • 층 별 비교
      • 각 층에서 수행되는 비교 횟수는 분할된 크기 * 분할된 개수로, 항상 O(n)이다.
      • 층 수는 log2n이다.
      • 즉, 모든 층에서 수행되는 비교 횟수는 O(nlog2n)이다.
    • 각 층에서 비교 후에 새로운 배열로 이동시키는 과정의 시간복잡도는 O(nlog2n)이다.
  • 모두 더하면 O(nlog2n)이다.

공간 복잡도

  • 입력과 같은 크기의 공간이 별도로 필요하므로 O(n)이다.

C++ 코드

#include <iostream>
#include <vector>

void PrintElements(const std::vector<int>& arr)
{
    for (const auto& e : arr)
        std::cout << e << " ";
    std::cout << std::endl;
}

void Merge(std::vector<int>& arr, int low, int mid, int high)
{
    int i = low;
    int j = mid + 1;
    int temp_idx = low;
    static std::vector<int> temp(arr);

    while ((i <= mid) && (j <= high))
    {
        if (arr[i] < arr[j])
            temp[temp_idx++] = arr[i++];
        else
            temp[temp_idx++] = arr[j++];
    }
    while (i <= mid)
        temp[temp_idx++] = arr[i++];
    while (j <= high)
        temp[temp_idx++] = arr[j++];

    while (low <= high)
    {
        arr[low] = temp[low];
        low++;
    }
}

void MergeSort(std::vector<int>& arr, int low, int high)
{
    if (low == high)
        return ;

    int mid = (low + high) / 2;

    MergeSort(arr, low, mid);
    MergeSort(arr, mid + 1, high);
    Merge(arr, low, mid, high);
}

int main()
{
    using namespace std;

    vector<int> arr = { 37, 10, 22, 30, 35, 13, 25, 24 };

    PrintElements(arr);
    MergeSort(arr, 0, arr.size() - 1);
    PrintElements(arr);
}

/* stdout
37 10 22 30 35 13 25 24 
10 13 22 24 25 30 35 37
*/

참고

  • 알기쉬운 알고리즘 (양성봉 저, 생능 출판)
반응형
저작자표시 (새창열림)

'SW개발 > 알고리즘' 카테고리의 다른 글

선택 문제 (Selection Problem)  (0) 2021.04.30
퀵 정렬 (Quick Sort)  (0) 2021.04.30
02. 알고리즘을 배우기 위한 준비  (0) 2021.04.30
보간 탐색(Interpolation Search)  (0) 2021.04.30
01. 알고리즘의 첫걸음  (0) 2021.04.30
'SW개발/알고리즘' 카테고리의 다른 글
  • 선택 문제 (Selection Problem)
  • 퀵 정렬 (Quick Sort)
  • 02. 알고리즘을 배우기 위한 준비
  • 보간 탐색(Interpolation Search)
Caniro
Caniro
  • Caniro
    Minimalism
    Caniro
  • 전체
    오늘
    어제
    • 전체보기 (319)
      • SW개발 (268)
        • Java Spring (6)
        • C++ (186)
        • Python (21)
        • Linux (16)
        • 알고리즘 (13)
        • Git (4)
        • Embedded (1)
        • Raspberrypi (9)
        • React (3)
        • Web (2)
        • Windows Device Driver (6)
      • IT(개발아님) (46)
        • Windows (26)
        • MacOS (7)
        • Utility (11)
      • 챗봇 짬통 (0)
      • 일상 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    unix
    알림
    Workspace
    Windows 11
    제외
    윈도우
    스프링 프레임워크 핵심 기술
    KakaoTalk
    EXCLUDE
    그림판
    SFC
    citrix workspace
    Solaris 10
    로지텍 마우스 제스처
    MacOS
    windows
    java
    mspaint
    dism
    맥북 카카오톡 알림 안뜸
    vscode
    spring
    SunOS 5.1
    시스템 복구
    logi options
    윈도우 명령어
    스프링
    백기선
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Caniro
합병 정렬 (Merge Sort)
상단으로

티스토리툴바