갱스타
갱스타의 블로그
갱스타
전체 방문자
오늘
어제
  • 분류 전체보기 (93)
    • TIL(Today I Learned) (10)
    • 노력만이 살길! (58)
      • 알고리즘 (29)
      • 네트워크 (3)
      • Python (1)
      • Spring Boot (1)
      • 합격하기 (0)
      • Adsp (3)
      • SQLD (10)
      • 데이터분석 (5)
      • 취업일기 (4)
      • IT 프로젝트 관리 (1)
      • 운영체제 (1)
    • Life (10)
      • 일상 그리고 리뷰 (10)
    • 기타 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 백준 알고리즘
  • 달팽이 반복문
  • 네트워크
  • 백준 2477번
  • 통신
  • 백준 참외밭
  • java 알고리즘
  • SWEA 13038
  • 싸피7기
  • 싸피
  • Get
  • 싸피합격
  • mac 단축키
  • 백준 달팽이
  • 백준
  • swea
  • post
  • 달팽이문제
  • 알고리즘
  • SW Expert Academy

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갱스타

갱스타의 블로그

노력만이 살길!/알고리즘

합병정렬(Merge Sort)

2019. 7. 24. 23:03

합병정렬 알고리즘

- 합병정렬은 입력이 2개의 부분문제로 분할되고, 부분문제의 크기가 1/2로 감소하는 분할정복 알고리즘

- 안정 정렬에 속함

- John von Neumann (존 폰 노이만)이 제안

 

합병정렬 알고리즘 psuedo - code

MergeSort(A,p,q)
입력 : A[P]~A[Q]
출력 : 정렬된 A[P]~ A[Q]
if(P<Q) {   //배열의 원소의 수가 2개 이상이면
 k = (p+q)/2   // k=반으로 나누기 위한 중간 원소의 인덱스    
 MergeSort(A,P,Q)   // 앞부분 재귀호출
 MergeSort(A,k+1,Q)  // 뒷부분 재귀호출
 A[P]~A[k] 와 A[k+1] ~ A[Q]를 합병

합병정렬 알고리즘 C code

# include <stdio.h>
# define MAX_SIZE 8
int sorted[MAX_SIZE] // 추가적인 공간이 필요

// i: 정렬된 왼쪽 리스트에 대한 인덱스
// j: 정렬된 오른쪽 리스트에 대한 인덱스
// k: 정렬될 리스트에 대한 인덱스
/* 2개의 인접한 배열 list[left...mid]와 list[mid+1...right]의 합병 과정 */
/* (실제로 숫자들이 정렬되는 과정) */
void merge(int list[], int left, int mid, int right){
  int i, j, k, l;
  i = left;
  j = mid+1;
  k = left;

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

  // 남아 있는 값들을 일괄 복사
  if(i>mid){
    for(l=j; l<=right; l++)
      sorted[k++] = list[l];
  }
  // 남아 있는 값들을 일괄 복사
  else{
    for(l=i; l<=mid; l++)
      sorted[k++] = list[l];
  }

  // 배열 sorted[](임시 배열)의 리스트를 배열 list[]로 재복사
  for(l=left; l<=right; l++){
    list[l] = sorted[l];
  }
}

// 합병 정렬
void merge_sort(int list[], int left, int right){
  int mid;

  if(left<right){
    mid = (left+right)/2 // 중간 위치를 계산하여 리스트를 균등 분할 -분할(Divide)
    merge_sort(list, left, mid); // 앞쪽 부분 리스트 정렬 -정복(Conquer)
    merge_sort(list, mid+1, right); // 뒤쪽 부분 리스트 정렬 -정복(Conquer)
    merge(list, left, mid, right); // 정렬된 2개의 부분 배열을 합병하는 과정 -결합(Combine)
  }
}

void main(){
  int i;
  int n = MAX_SIZE;
  int list[n] = {21, 10, 12, 20, 25, 13, 15, 22};

  // 합병 정렬 수행(left: 배열의 시작 = 0, right: 배열의 끝 = 7)
  merge_sort(list, 0, n-1);

  // 정렬 결과 출력
  for(i=0; i<n; i++){
    printf("%d\n", list[i]);
  }
}
https://gmlwjd9405.github.io/2018/05/08/algorithm-merge-sort.html

 

 

 

 

 

 

 

출처 

https://gmlwjd9405.github.io/2018/05/08/algorithm-merge-sort.html

'노력만이 살길! > 알고리즘' 카테고리의 다른 글

[Java] 1954번 달팽이 - 재귀함수 사용 (SW Expert Academy )  (0) 2022.02.07
[Java] 1954 달팽이 숫자 (SW Expert Academy ) - for문 사용  (0) 2022.02.07
2001 파리 퇴치 (SW Expert Academy )  (0) 2022.02.05
시간복잡도의 점근적 표기법  (2) 2019.07.24
분할 정복 알고리즘  (1) 2019.07.23
    '노력만이 살길!/알고리즘' 카테고리의 다른 글
    • [Java] 1954 달팽이 숫자 (SW Expert Academy ) - for문 사용
    • 2001 파리 퇴치 (SW Expert Academy )
    • 시간복잡도의 점근적 표기법
    • 분할 정복 알고리즘
    갱스타
    갱스타
    열심히 배워보자

    티스토리툴바