다룰 내용
- 분할과 정복 방법
- 재귀(Recursion, 순환)
- 분할과 정복에 의한 정렬 알고리즘(병합정렬과 퀵정렬)
우선, 파이썬 코드로 다음을 나타내보자. (built-in 함수인 max()를 사용하지 않았다.)
(결국 시간 복잡도는 O(n)
으로 같음)
def maximum(a, first, last):
if (first == last):
return a[first]
else: # if (first < last)
mid = (first + last) // 2
lmax = maximum(a, first, mid-1)
rmax = maximum(a, mid+1, last)
if lmax > rmax:
return lmax
else:
return rmax
main program : maximum(a, 0, len(a)-1)을 호출
T(n) : maximum(a, 0, n-1)의 수행시간 (원소 비교 횟수)
T(n) = 0 // n = 1
= 2T(n/2) + 1 // n > 1
= 2[2T(n/2^2) + 1]
= 2^2 * T(n/2^2) + 2 + 1
= 2^2 [2T(n/2^3) + 1] + 2 + 1
= 2^3 * T(n/2^3) + 2^2 + 2 + 1
...
= 2^k * T(n/2^k) + 2^(k-1) + ... + 1
= 2^k * T(n/2^k) + 2^k
...
n * 1 + n = 2n
T(n)은 O(N)
이다.
f(n) = a (a는 상수) if n = 1 = f(n-1) + bn (b는 상수) if n > 1
f(n) = f(n-1) + bn
= [f(n-2) + b(n-1)] + bn = f(n-2) + b[(n-1) + n]
= [f(n-3) + b(n-2)] + b[(n-1) + n] = f(n-3) + b[(n-2) +(n-1) + n]
= ...
= f(n-k) + b[(n-(k-1)) + ... + (n-1) + n]
= f(n-k) + b(n-k+1 + n)k/2 -> 등차수열의 합 공식
...
(n-k = 1 일 때)
= f(1) + b(n+2)(n-1)/2
따라서 f(n)은 O(N^2)
의 시간 복잡도를 갖는다.
n = 2^k 일 경우
f(n) = a (a는 상수) if n = 1
= 2f(n/2) + b (b는 상수) if n > 1
f(n) = 2 * f(n/2) + b = 2[2f(n/2^2) + b] + b
= 2^2 * f(n/2^2) + 2b + b = 2^2[2f(n/2^3) + b] + 2b + b
= 2^3 * f(n/2^3) + 2^2b + 2b + b = 2^3[2f(n/2^4) + b] + 2^2b + 2b + b
...
= 2^k * f(n/2^k) + (2^(k-1) + ... + 2^2 + 2 + 1)b
= 2^k * f(n/2^k) + (2^k - 1)b
...
n = 2^k라고 하면,
= nf(1) + (n-1) = 2n - 1
따라서 f(n)은 O(N)
의 시간 복잡도를 갖는다. (n이 2^k가 아닐 경우에도 만족한다.)
n = 2^k 일 경우
f(n) = a (a는 상수) if n = 1
<= 2f(n/2) + bn (b는 상수) if n > 1
f(n) <= 2 * f(n/2) + bn
<= 2[2f(n/2^2) + bn/2] + bn
<= 2^2 * f(n/2^2) + bn + bn
<= 2^2[2f(n/2^3) + bn/2^2] + 2bn
<= 2^3 * f(n/2^3) +3bn
...
<= 2^k * f(n/2^k) + kbn
...
n / 2^k = 1 이라고 하면, k = logn
= nf(1) + bn(logn) = an + bnlogn
따라서 f(n)은 O(NlogN)
의 시간 복잡도를 갖는다. (n이 2^k가 아닐 경우에도 만족한다.)
def binarySearch(A, item, left, right):
if left <= right:
mid = (left + right)//2
if item == A[mid]:
return mid
elif item < A[mid]:
return binarySearch(A, item, left, mid-1)
else:
return binarySearch(A, item, mid+1, right)
수행시간 분석
T(n) : binarySearch(A, item, 0, n-1)을 수행할 때 원소 비교 횟수
T(n) = 0 if n = 1
<= T(n/2) + 1 if n > 1
대략적인 분석 (X^n을 계산하는 함수 exp3(x,n) 수행시간 분석과 유사함)
...
T(n) <= T(n/2^k) + k
...
n/2^k = 1 (즉, k = log n) 일 때,
T(n) <= T(1) + logn
참고 : exp3(x,n)을 다루는 부분
수행시간 : item과 A의 원소 비교횟수 O(log N)