퀵 정렬과 합병 정렬은 리스트를 분할하고 정복하는 방법으로 정렬한다.

 

이 두 가지 정렬은 특징은 다음과 같다.

 

퀵 정렬 : 평균 복잡도는 O(NlogN) 이지만 최악의 복잡도는 O(N^2)이다.

 

합병 정렬 : 시간 복잡도는 O(NlogN)을 보장한다. 하지만 정렬을 하기 위해서 임시 배열을 사용하기 때문에

 

추가적인 메모리가 필요하다.

 

[C++]

#include <iostream>
using namespace std;

// 병합정렬 특 : 추가적인 메모리를 요구함
int size = 8;
int sorted[8]; // 정렬 배열은 무조건 전역 변수로 선언

void merge(int a[], int m, int middle, int n) {
  int i = m;
  int j = middle + 1;
  int k = m;
  // 작은 순서대로 배열에 삽입
  while (i <= middle && j <= n) {
    if (a[i] <= a[j]) {
      sorted[k] = a[i++];
    } else {
      sorted[k] = a[j++];
    }
    k++;
  }
  // 남은 데이터도 삽입
  if (i > middle) { // i가 먼저 끝남
    for (int t = j; t <= n; t++)
      sorted[k++] = a[t];
  } else {
    for (int t = i; t <= middle; t++)
      sorted[k++] = a[t];
  }
  // 정렬된 데이터를 실제 배열로 삽입
  for (int t = m; t <= n; t++)
    a[t] = sorted[t];
}

// IDEA : 일단 정확히 반으로 나누고 나중에 정렬
void mergeSort(int a[], int m, int n) {
  // 크기가 1보다 큰 경우
  if (m < n) {
    int middle = (m + n) / 2;
    mergeSort(a, m, middle);
    mergeSort(a, middle + 1, n);
    merge(a, m, middle, n);
  }
}

int main(void) {
  int arr[size] = {7, 6, 5, 8, 3, 5, 9, 1};
  mergeSort(arr, 0, size - 1);
  for (int i = 0; i < size; i++)
    cout << arr[i] << " ";
  return 0;
}
 

[JAVA]

package MergeSort;

public class MergeSort {

    static void merge(int[] list, int left, int mid, int right, int size) {
        int[] storage = new int[size];
        int i = left;
        int j = mid + 1;
        int k = left;

        // 분할 정렬된 list 들의 합병
        while (i <= mid && j <= right) {
            if (list[i] <= list[j])
                storage[k] = list[i++];
            else
                storage[k] = list[j++];
            k++;
        }

        // 선택받지 못한 값들을 차례대로 채워 넣는다
        if (i > mid) {
            for (int l = j; l <= right; l++)
                storage[k++] = list[l];
        } else {
            for (int l = i; l <= mid; l++)
                storage[k++] = list[l];
        }

        // 임시 배열에 저장된 값을 원래 배열로 옮김
        for (int l = left; l <= right; l++)
            list[l] = storage[l];
        
    }

    static void merge_sort(int[] list, int left, int right, int size) {
        if (left < right) {
            int mid = (left + right) / 2;
            merge_sort(list, left, mid, size); // 기준 왼쪽 정렬
            merge_sort(list, mid + 1, right, size); // 기준 오른쪽 정렬
            merge(list, left, mid, right, size); // 양쪽 정렬된 리스트를 합친다
        }
    }

    public static void main(String[] args) {
        int[] list = new int[10000];
        int[] clist = new int[10000];
        int size = list.length;
        
        // 역순으로 값을 넣는다.
        for(int i=0;i<size;i++) {
            list[i] = size-i;
            clist[i] = size-i;
        }
        
        // 병합 정렬 속도 측정
        long st = System.currentTimeMillis();
        merge_sort(list, 0, size - 1, size);
        long et = System.currentTimeMillis();
        System.out.println("mergesort time(nlogn) : "+(et-st));
        
        // 버블 정렬  측정
        st = System.currentTimeMillis();
        for(int i=0;i<size-1;i++) {
            for (int j = i+1; j < size; j++) {
                if(clist[i]>clist[j]) {
                    int tmp = clist[j];
                    clist[j] = clist[i];
                    clist[i] = tmp;
                }
            }
        }
        
        et = System.currentTimeMillis();
        System.out.println("bubble sort time(n^2) : "+(et-st));

    }

}
 

 

 

Merge Sort(NlogN)  vs Bubble Sort(N^2)  속도 비교

 

배열 사이즈를 동적으로 바꿔가면서 배열의 값들을 역순으로 넣고 비교했다.

 

사이즈가 적을 때는 버블 소트가 속도가 확실히 빠르지만, 충분히 큰 사이즈를 넣어줬을 때 부터는 

 

병합 정렬이 확실히 빨랐다.

 

https://www.youtube.com/watch?v=YJ-OUnZu7nQ&list=PLRx0vPvlEmdDHxCvAQS1_6XV4deOwfVrz&index=9

 

'알고리즘 > 자료구조' 카테고리의 다른 글

[JAVA] 이진 탐색 (Binary Search)  (0) 2019.04.21
퀵정렬 알고리즘 ( Quick Sort )  (0) 2019.04.21

+ Recent posts