Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 컴퓨터구조론 5판
- Python
- 개발자스터디
- 99클럽
- 중심사회
- wil
- 개인공부
- til
- 운영체제
- 프로그래머스
- 스파르타내일배움캠프TIL
- AWS
- 스파르타내일배움캠프WIL
- Flutter
- 자바
- Spring
- 백준
- 스파르타코딩클럽
- MySQL
- 부트캠프
- 99일지
- 컴퓨터개론
- 소프트웨어
- 국비
- java
- 내일배움캠프
- 스파르타내일배움캠프
- 항해
- 코딩테스트
- 개발자블로그
Archives
- Today
- Total
컴공생의 발자취
[Algorithm] 합병정렬 MergeSort - C언어 본문
728x90
반응형
분할 정복 알고리즘(Divide-and-Conquer)
합병정렬(MergeSort)
: 입력이 2개의 부분문제로 분할되고, 부분문제의 크기가 1/2로 감소하는 분할
- n개의 숫자들을 n/2개의 부분문제로 분할(Divide)
- 각각의 부분문제들을 해결(Conquer)
- 재귀적으로 합병 정렬(Merge)
개념 설명
Pseudo code
MergeSort(A, p, q)
입력 : A[p] ~ A[q]
출력 : 정렬된 A[p] ~ A[q]
if(p < q){ // 배열의 원소의 수가 2개 이상이면
k = [(p+q)/2] // k : 반으로 나누기 위한 중간 원소의 인덱스(내림으로)
MergeSort() // 앞부분 재귀 호출
MergeSort() // 뒷부분 재귀 호출
A[p] ~ A[k]와 A[k+1] ~ A[q]를 합병
}
시간복잡도
- 시간복잡도 : O(nlogn)
-> (층수) X O(n) = log2(n) X O(n) = O(nlogn)
- 공간복잡도 : O(n)
단점
- 입력을 위한 메모리 공간 외에 추가로 입력과 같은 크기의 공간(임시 배열)이 별도로 필요
- 2개의 정렬된 부분을 하나로 합병하기 위해, 합병된 결과를 저장할 곳이 필요함
구현 - C언어
#include <stdio.h>
#define size 8
// 배열의 값을 분할하는 과정 + Merge
void MergeSort(int arr[], int left, int right);
// 배열의 값을 정렬후 합치는 과정
void Merge(int arr[], int left, int mid, int right);
int main(void) {
int arrA[size] = {37, 10, 22, 30, 35, 13, 25, 24};
// 정렬 전
printf("before merge sort\n");
for (int i = 0; i < size; i++) {
printf(" [%d] %d", i, arrA[i]);
}
printf("\n");
// MergeSort 수행
MergeSort(arrA, 0, size - 1);
// 정렬 후
printf("after merge sort\n");
for (int i = 0; i < size; i++) {
printf(" [%d] %d", i, arrA[i]);
}
printf("\n");
return 0;
}
void MergeSort(int arr[], int left, int right) {
int mid;
if (left < right) {
mid = (left + right) / 2; // 배열의 중간 인덱스 계산 - divide
MergeSort(arr, left, mid); // 중간 인덱스 기준 왼쪽 배열 정렬
MergeSort(arr, mid + 1, right); // 중간 인덱스 기준 오른쪽 배열 정렬
Merge(arr, left, mid, right); // 정렬된 2개의 배열 합병 - merge
// 정렬 과정
printf("procedure : ");
for (int i = 0; i < size; i++) {
printf(" [%d] %d", i, arr[i]);
}
printf("\n");
}
}
void Merge(int arr[], int left, int mid, int right) {
int tmp[size]; // 정렬한 배열 저장 공간 - 추가 공간
int l_idx = left; // 정렬될 왼쪽 배열의 인덱스
int r_idx = mid + 1; // 정렬될 오른쪽 배열의 인덱스
int sort_idx = left; // 정렬된 배열의 인덱스
// 분할된 배열의 정렬값 추가 공간에 복사
while (l_idx <= mid && r_idx <= right) {
// 오른쪽 배열의 값이 더 클 경우
if (arr[l_idx] <= arr[r_idx])
// 왼쪽 배열의 값을 추가 공간에 복사
tmp[sort_idx++] = arr[l_idx++];
// 왼쪽 배열의 값이 더 클 경우
else
// 오른쪽 배열의 값을 추가 공간에 저장
tmp[sort_idx++] = arr[r_idx++];
}
// 왼쪽 배열의 값이 모두 추가 공간에 복사된 경우
if (l_idx > mid) {
// 오른쪽 배열의 값을 추가 공간에 일괄 복사
for (int r = r_idx; r <= right; r++)
tmp[sort_idx++] = arr[r];
}
// 오른쪽 배열의 값이 모두 추가 공간에 복사된 경우
else {
// 왼쪽 배열의 값을 추가 공간에 일괄 복사
for (int l = l_idx; l <= mid; l++)
tmp[sort_idx++] = arr[l];
}
// 정렬되어 추가 공간에 복사된 값을 원본 배열로 재복사
for (int idx = left; idx <= right; idx++) {
arr[idx] = tmp[idx];
}
}
결과
728x90
반응형
'📖 이론 > 컴퓨터 알고리즘' 카테고리의 다른 글
[Algorithm] 선택 문제 Selection Problem - C언어 (0) | 2023.06.11 |
---|---|
[Algorithm] 퀵 정렬 QuickSort - C언어 (0) | 2023.04.28 |