병합정렬(Merge Sort)


병합정렬 개념, 병합정렬이란?
병합정렬은 안정정렬에 속하며 분할 정복 알고리즘 중 하나이다. (분할정복은 문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음 결과를 모아서 원래의 문제를 해결하는 전략으로 순환 호출을 이용하여 구현한다)
하나의 문제를 두 개의 균등한 크기로 분할하고 분할된 작은문제들을 정렬한다. 그렇게 정렬된 부분리스트를 최종적으로 병합하여 전체가 정렬된 리스트가 되게하는 방법이다. 각 문제는 크기가 1이 될때까지 재분할하여 정렬을 시도한다.
보통 재귀함수로 구현된다.
그림으로 이해하기


시간 복잡도
참고 https://rosweet-ai.tistory.com/52
최고/최악
- O(nlog₂n)
장단점 (사용하면 좋은/나쁜 상황)
장점
- 안정 정렬방법으로, 데이터의 분포에 영향을 덜받는다. 즉 입력데이터가 무엇이든 정렬 시간은 동일하다.
- 만약 레코드를 연결리스트(Linked List)로 구성하면 링크 인덱스만 변경되므로 데이터의 이동은 무시할수 있을정도로 작아진다.
- 제자리 정렬로 구현할 수 있다.
- 크기가 큰 레코드를 정렬할 경우 연결리스트를 사용하면, 퀵정렬을 포함한 다른 어떤 정렬방법보다 효율적이다.
단점
- 배열로 구성할 경우, 제자리정렬(in-place sorting)이 아니기 때문에 추가적인 공간이 필요하다.
- 원소의 크기가 큰 경우에 이동횟수가 많아져 매우 큰 시간적 낭비를 초래한다.
소스코드 예시와 설명 (백준 2751문제, 1517_ java)
백준 2751 문제 병합정렬로 풀기
문제 - https://www.acmicpc.net/problem/2751
import java.io.*;
public class 병합정렬_2751 {
public static int[] A, tmp;
public static long result;
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
A = new int[N+1];
tmp = new int[N+1];
for(int i=1; i<=N; i++){
A[i] = Integer.parseInt(br.readLine());
}
mergetSort(1,N);
for(int i=1;i<=N;i++){
bw.write(A[i]+"\n");
}
bw.flush();
bw.close();
}
public static void mergetSort(int s, int e){
if(e-s<1) return;
int m = s+(e-s)/2;
mergetSort(s,m);
mergetSort(m+1,e);
for(int i=s; i<=e; i++){
tmp[i] = A[i];
}
int k=s;
int index1=s;
int index2=m+1;
while(index1 <=m && index2<=e){
if(tmp[index1]>tmp[index2]){
A[k]=tmp[index2];
k++;
index2++;
} else {
A[k]=tmp[index1];
k++;
index1++;
}
}
while(index1<=m){
A[k] = tmp[index1];
k++;
index1++;
}
while(index2<=e){
A[k]=tmp[index2];
k++;
index2++;
}
}
}
백준 1517 문제 병합정렬로 풀기
문제 - https://www.acmicpc.net/problem/1517
import java.io.*;
import java.util.*;
public class 병합정렬_버블소트프로그램_1517 {
public static int[] A, tmp;
public static long result;
public static void main(String[] args)throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
A = new int[N+1];
tmp = new int[N+1];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i=1;i<=N;i++){
A[i] = Integer.parseInt(st.nextToken());
}
result = 0;
mergetSort(1,N);
bw.write(result+" ");
bw.flush();
bw.close();
}
public static void mergetSort(int s, int e){
if(e-s<1)return;
int m = s+(e-s)/2;
mergetSort(s,m);
mergetSort(m+1, e);
for(int i=s;i<=e;i++){
tmp[i]=A[i];
}
int k=s;
int index1=s;
int index2=m+1;
while(index1<=m&& index2 <=e){
if(tmp[index1]>tmp[index2]){
A[k] = tmp[index2];
result = result+index2-k;
k++;
index2++;
}else{
A[k] = tmp[index1];
k++;
index1++;
}
}
while(index1<=m){
A[k]=tmp[index1];
k++;
index1++;
}
while(index2 <= e){
A[k]=tmp[index2];
k++;
index2++;
}
}
}
'Algorithm > 알고리즘 원리' 카테고리의 다른 글
| [Algoritm] 초보자도 쉽게이해하는 기수정렬 알고리즘! 백준문제풀이, java (0) | 2025.11.27 |
|---|---|
| [Algoritm] 초보자도 쉽게이해하는 퀵정렬 알고리즘! 백준문제풀이, java (0) | 2025.11.20 |
| [Algoritm]초보자도 쉽게 삽입정렬 이해하기! - java언어, 백준문제풀이 (0) | 2025.11.19 |
| [Algoritm]초보자도 쉽게 선택정렬 이해하기! - java언어, 백준문제풀이 (0) | 2025.11.18 |
| [Algoritm] 초보자도 쉽게 버블정렬 이해하기! - java 예시, 버블정렬 문제풀이 (0) | 2025.11.17 |