분할 정복(Divide-and-Conquer)알고리즘이란 주어진 문제의 입력을 분할하여 문제를 해결(정복)하는 방식의 알고리즘이다.
ㅣ37 10 22 30 35 13 25 24ㅣ
↙ ↘
ㅣ37 10 22 30ㅣ ㅣ35 13 25 24ㅣ
↙ ↘
ㅣ37 10 22 30ㅣ 분할 ㅣ35 13 25 24ㅣ
↙ ↘ ↙ ↘
ㅣ37 10ㅣ ㅣ22 30ㅣ ㅣ35 13ㅣ ㅣ25 24ㅣ
↙ ↘ ↙ ↘ ↙ ↘ ↙ ↘
ㅣ37ㅣ ㅣ10ㅣ ㅣ22ㅣ ㅣ30ㅣ ㅣ35ㅣㅣ13ㅣㅣ25ㅣㅣ24ㅣ
//설명 37 10 22 30 35 13 25 24 8개의 입력을 index가 1개가 남을때까지 분할 하였다.
분할 할때는 f(a,(a+b)/2);
f((a+b)/2+1,b);
나누기만 하면 되니깐 O(1)의 시간이 걸린다.
이제 합병 즉, 잘개 쪼갠 index들을 합쳐야한다.
ㅣ37ㅣ ㅣ10ㅣ ㅣ22ㅣ ㅣ30ㅣ ㅣ35ㅣ ㅣ13ㅣ ㅣ25ㅣ ㅣ24ㅣ 합병을 하기 위해서 위에 글을 이어서 가보자.
분할에서 보이듯이 index가 한개가 남을때까지 나눈 상태이다.
합병을 할때는 나눈것들 끼리 비교하면서 합쳐야한다.
ㅣ37 10ㅣ을 ㅣ37ㅣ ㅣ10ㅣ으로 나누었다.
만약 A와 B의 크기가 각각 n과 m이라면, 최대 비교 횟수는 (n+m-1)이다.
합병 시에 2개의 숫자 즉 처음에는 37과 10 중에 '승자' 작은숫자가 탄생하게 되고 작은 숫자는 합병된 C라는 배열에 저장된다. A,B의 모든 (n+m)개의 숫자들은 결국 배열 C에 저장 되지만 마지막에 저장되는 숫자는 비교 할 숫자가 없어서 최대 비교 횟수는 (n+m-1) 여기에서 -1은 다시 설명하자면 ㅣ37ㅣ ㅣ10ㅣ ㅣ22ㅣ ㅣ30ㅣ을 합병해서 ㅣ10 37ㅣ ㅣ22 30ㅣ으로 합병 했다고 가정해보자 ㅣ10 37ㅣ은 n이다. ㅣ22 30ㅣ은 m이다.
→n번 →m번 (다시 돌아 갈 일 없다. 그래서 n+m)
다시 처음으로 돌아갈 필요 없이 n개도 n번만 보면 되고 m개→도 m번→만 보면 된다.
-1은 10 22 30 순으로 합병이 되고 마지막 남은 37은 비교 할 숫자가 없다. 그래서 -1 이 된다.
3층ㅣ37ㅣ ㅣ10ㅣ ㅣ22ㅣ ㅣ30ㅣ ㅣ35ㅣ ㅣ13ㅣ ㅣ25ㅣ ㅣ24ㅣ n/8
↘ ↙ ↘ ↙ 합병 ↘ ↙ ↘ ↙
2층 ㅣ10 37ㅣ ㅣ22 30ㅣ ㅣ13 35ㅣ ㅣ24 25ㅣ n/4
↘ ↙ ↘ ↙
1층 ㅣ10 22 30 37ㅣ ㅣ13 24 25 35ㅣ n/2
↖ ↗
ㅣ10 13 22 24 25 30 35 37ㅣ n개
층별로 모든 원소가 다 참여 하고 있으니깐 O(n)이다.
결과적으로 합병 정렬의 시간복잡도는 (층수)xO(n) =log2n*O(n) = O(nlogn)이다.
층수도 n에 관계가 있는 것을 확인 할 수 있다.