📖 분할정복
정의
- 큰 문제를 작은 문제로 쪼개어 해결해 나가는 방식
설계 전략
- 분할(Divide): 해결할 문제를 여러개의 작은 부분으로 나눔
- 정복(Conquer): 나눈 작은 문제를 각각 해결
- 통합(Combine): 해결된 해답을 모음
💬 응용 : 거듭 제곱
반복문 알고리즘: O(n)
재귀 알고리즘: O(n)
분할 정복 알고리즘: O(log2N)
💬 응용 : 병합 정렬
정의
- 여러 개의 정렬된 자료의 집합을 병합하여 한 개의 정렬된 집합으로 만드는 방식
활용 방식
- 자료를 최소 단위의 문제까지 나눈 후 차례대로 정렬하여 최종 결과 얻음
시간 복잡도 : O(n log n)
◾ 병합 정렬 과정
- [ 69, 10, 30, 2, 16, 8, 31, 22 ]를 병합 정렬하는 과정
1. 분할 단계
- 전체 자료 집합에 대해, 최소 크기의 부분집합이 될 때까지 분할
2. 병합 단계
- 2개의 부분집합을 정렬하면서 하나의 집합으로 병합
병합 정렬 알고리즘
public class 병합정렬 {
public static void main(String[] args) {
int[] arr = {69, 10, 30, 2, 16, 8, 31, 22};
int[] tmp = new int[arr.length];
mergeSort(arr, tmp, 0, arr.length-1);
for(int i : arr)
System.out.println(i);
}
static void mergeSort(int[] arr, int[] tmp, int start, int end) {
if(start < end) {
int mid = (start + end) / 2;
mergeSort(arr, tmp, start, mid);
mergeSort(arr, tmp, mid+1, end);
int startL = start, startR = mid+1;
int idx = startL;
while(startL <= mid || startR <= end) {
if(startR > end
|| (startL <= mid && arr[startL] < arr[startR]))
tmp[idx++] = arr[startL++];
else tmp[idx++] = arr[startR++];
}
for (int i = start; i <= end; i++) {
arr[i] = tmp[i];
}
}
}
}
💬 응용 : 퀵 정렬
정의
병합 정렬과 차이점
- 병합정렬은 그냥 두 부분으로 나누는 반면, 퀵 정렬을 분할 시 기준 아이템 중심으로 위치 시킴
- 각 부분 정렬이 끝난 후 병합정렬은 '병합'이란 후처리 작업 필요, 하지만 퀵정렬은 필요 없음
시간 복잡도 : O(n log n)
◾ 아이디어
P(피봇)값들 보다 큰 값은 오른쪽, 작은 값은 왼쪽 집합에 위치
P를 두 집합의 가운데 위치
피봇 선택 방법
- 왼쪽 끝 / 오른쪽 끝 / 임의의 세 개 값 중 중간값
- 일반적으로 왼쪽 끝으로 많이 함
◾ 퀵 정렬 과정
- [ 3, 2, 4, 6, 9, 1, 8, 7, 5 ] 를 퀵 정렬하는 과정
1. i 인덱스, j 인덱스 순차적으로 비교하며 조건에 안맞는 숫자 찾기
- i 인덱스 : 피봇보다 큰 값 찾아야 함
- j 인덱스 : 피봇보다 작은 값 찾아야 함
2. 조건이 안맞는 두 수 위치 교환
3. i와 j가 교차할 때, j와 피봇 위치 교환
4. 다시 위 과정 반복
- 왼쪽 배열은 위치 변환 없음
- 오른쪽 배열의 피봇 6 중심으로 진행
◾ 퀵 정렬 알고리즘
public class 퀵정렬 {
public static void main(String[] args) {
int[] arr = {3, 2, 4, 6, 9, 1, 8, 7, 5};
quickSort(arr, 0, arr.length-1);
for(int i : arr)
System.out.println(i);
}
static void quickSort(int[] arr, int start, int end) {
if(start < end) {
int p = start, i = start+1, j = end;
while(i <= j) {
while(arr[i] <= arr[p]) i++;
while(arr[j] > arr[p]) j--;
if(i < j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
int tmp = arr[p];
arr[p] = arr[j];
arr[j] = tmp;
quickSort(arr, start, j-1);
quickSort(arr, j+1, end);
}
}
}