ν’€μŠ€νƒ μ›ΉπŸŒ 개발자 지망생 πŸ§‘πŸ½β€πŸ’»
βž• 인곡지λŠ₯ 관심 πŸ€–


Categories


Recent views

  • 1
  • 2
  • 3
  • 4
  • 5

병합 μ •λ ¬

Merge Sort(병합 μ •λ ¬)

πŸ—£οΈ 좜처

_Introduction to Algorithm, 3rd, Cormen_을 ν† λŒ€λ‘œ μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€

병합 정렬은 divide-and-conquer μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•˜μ—¬ μž¬κ·€μ μœΌλ‘œ μ •λ ¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

μ „λ°˜μ μœΌλ‘œ 퀡정렬보닀 뒀떨어지고 데이터 크기 만큼 λ©”λͺ¨λ¦¬κ°€ 더 ν•„μš”ν•œλ‹€.

μ•ˆμ •λœ μ •λ ¬(stable sort)μ΄λ―€λ‘œ, λ§Œμ•½ 같은 크기의 μ›μ†Œκ°€ λ‘˜μ΄ μ‘΄μž¬ν•˜λ©΄, λ‘˜μ˜ μ„ ν›„ 관계가 λ°”λ€Œμ§€ μ•ŠλŠ”λ‹€.

Merge ν•¨μˆ˜

λ¨Όμ € Merge ν•¨μˆ˜μ΄λ‹€. Merge-Sort ν•¨μˆ˜ 내뢀에 싀행될 ν•¨μˆ˜λ‘œ, λ‚˜λˆˆ 두 개의 μ •λ ¬λœ 배열을 ν•˜λ‚˜λ‘œ ν•©μΉ˜λŠ” 역할을 ν•œλ‹€.

Merge(A,p,q,r)
	n1=q-p+1
	n2=r-q
	//let L[1..n1+1] and R[1..n2+1] be new arrays
	for i = 1 to n1
	    L[i] = A[p+i-1]
	for j = 1 to n2
	    R[j] = A[q+j]
	L[n1+1] = inf
	R[n2+1] = inf
	i = 1
	j = 1
	for k = p to r // 루프 λΆˆλ³€μ„± λŒ€μƒ 루프
	    if L[i]<=R[j]
	        A[k] = L[i]
	        i = i + 1
	    else A[k] = R[j]
	        j = j + 1

μœ„ κ³Όμ •μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” $O(n)$이닀.

  • μ‘΄μž¬ν•˜λŠ” for loop듀이 λͺ¨λ‘ n에 λΉ„λ‘€ν•˜μ—¬ 진행됨 즉, n에 λŒ€ν•œ μ„ ν˜• ν•¨μˆ˜κΌ΄
  • μ΄μ™Έμ˜ μ½”λ“œλŠ” λͺ¨λ‘ μƒμˆ˜ μ‹œκ°„μž„.

Merge ν•¨μˆ˜μ˜ 루프 λΆˆλ³€μ„±

μ΄λ•Œ, 17번째 쀄뢀터 λ§ˆμ§€λ§‰ κΉŒμ§€μ˜ for λ£¨ν”„μ˜ 루프 λΆˆλ³€μ„±μ€ λ‹€μŒκ³Ό 같이 λ³΄μ‘΄λœλ‹€.

루프 λΆˆλ³€μ„±(Loop invariant) κ°€μ • :

μ˜€λ¦„μ°¨μˆœ 병합 μ •λ ¬μ—μ„œ λΆ€λΆ„λ°°μ—΄ $A[p..k-1]$은 $L[1..n1+1]$κ³Ό $R[1..n2+1]$의 μ›μ†Œλ“€ 쀑 $k - p$ 개의 κ°€μž₯ μž‘μ€ μ›μ†Œλ“€λ‘œ 이루어져 있으며, μ •λ ¬λ˜μ–΄ μžˆλ‹€. λ˜ν•œ, $L, R$ λ°°μ—΄ λ‚΄μ—μ„œ ν˜„μž¬ 아직 $A$ 배열에 μΆ”κ°€λ˜μ§€ μ•Šμ€ μ›μ†Œλ“€μΈ $L[i]$와 $R[j]$λŠ” $L, R$ λ°°μ—΄ λ‚΄μ—μ„œ κ°€μž₯ μž‘μ€ μ›μ†Œμ΄λ‹€.

μ΄ˆκΈ°ν™”μ—μ„œμ˜ 루프 λΆˆλ³€μ„±:

루프에 μ§„μž…ν•˜λ©΄μ„œ $k = p$이며, $A[p…k-1]$은 λΉ„μ–΄μžˆμœΌλ―€λ‘œ, $k-p(0)$개의 κ°€μž₯ μž‘μ€ μ›μ†Œλ“€λ‘œ 이루어져 있고, μ •λ ¬λ˜μ–΄ μžˆλ‹€. λ˜ν•œ $L$κ³Ό $R$ 배열은 각각 μ •λ ¬λ˜μ–΄ μžˆμœΌλ―€λ‘œ, $L[1], R[1]$은 각자 λ°°μ—΄μ—μ„œ κ°€μž₯ μž‘μ€ μ›μ†Œμ΄λ‹€. 즉, 루프 λΆˆλ³€μ„±μ΄ λ³΄μ‘΄λœλ‹€.

μœ μ§€μ—μ„œμ˜ 루프 λΆˆλ³€μ„±:

λ¨Όμ € $L[i] <= R[j]$인 경우, $L[i]$λŠ” $A[k] = L[i]$ 이전에 $A$에 ν¬ν•¨λ˜μ§€ μ•Šμ€ $L$ λ‚΄μ—μ„œ κ°€μž₯ μž‘μ€ μ›μ†Œμ΄λ©°, $A[k] = L[i]$ 이후에 $A[p…k]$λŠ” $k-p+1$개의 μ •λ ¬λœ κ°€μž₯ μž‘μ€ μ›μ†Œλ“€μ„ 가지고 있게 λœλ‹€. 이후 $k$와 $i$κ°€ 1μ”© μ¦κ°€ν•˜λ©΄μ„œ 루프 λΆˆλ³€μ„±μ„ λ³΄μ‘΄ν•œλ‹€.

$R[j] < L[i]$인 경우, 16, 17번째 μ€„μ˜ μ½”λ“œκ°€ λ˜‘κ°™μ€ ν–‰λ™μœΌλ‘œ 루프 λΆˆλ³€μ„±μ„ λ³΄μ‘΄ν•œλ‹€.

μ’…λ£Œμ—μ„œμ˜ 루프 λΆˆλ³€μ„±:

$k = r + 1$이 λ˜λ©΄μ„œ, $A[p..k-1]$ 즉, $A[p..r]$은 $k-p=r-p+1$개의 $L[1..n1+1], R[1..n2+1]$μ—μ„œ κ°€μž₯ μž‘μ€ μ •λ ¬λœ μ›μ†Œλ“€μ„ κ°€μ§€κ²Œ λœλ‹€. μ΄λ•Œ $L,R$μ—λŠ” 각각 λ¬΄ν•œλŒ€μ˜ μ›μ†Œλ§Œ ν•˜λ‚˜μ”© κ°€μ§€κ²Œ λ˜λ―€λ‘œ, 루프 λΆˆλ³€μ„±μ„ λ³΄μ‘΄ν•œλ‹€.

Merge-Sort ν•¨μˆ˜

이 λ‹€μŒμ€ Merge-Sort ν•¨μˆ˜μ΄λ‹€. 전체 λ°°μ—΄ A의 λΆ€λΆ„λ°°μ—΄ $A[p..r]$을 또 λ‹€λ₯Έ λ‘κ°œμ˜ λΆ€λΆ„ λ°°μ—΄ $A[p..q]$와 $A[q+1..r]$둜 λ‚˜λˆ„μ–΄ μ •λ ¬ν•˜λŠ” 역할을 ν•˜λ©°, μž¬κ·€ ꡬ쑰λ₯Ό ν¬ν•¨ν•˜κ³  μžˆλ‹€.

Merge-Sort(A,p,r)
if p &#38;#60; r
    q = (p+r)//2
    Merge-Sort(A, p, q)
    Merge-Sort(A, q+1, r)
    Merge(A, p, q, r)

$p >= r$이 λ˜λŠ” μˆœκ°„, λ°°μ—΄μ—λŠ” ν•˜λ‚˜μ˜ μ›μ†Œλ§Œ λ‚¨μœΌλ―€λ‘œ ꡳ이 μ •λ ¬ν•˜μ§€ μ•ŠλŠ”λ‹€.

전체적인 병렬 μ •λ ¬μ˜ λ™μž‘μ€ μ•„λž˜μ— κ·Έλ¦Ό(Figure 1)으둜 λ¬˜μ‚¬λ˜μ–΄ μžˆλ‹€.

divide-and-conquer μ•Œκ³ λ¦¬μ¦˜ 뢄석

μ΄λŸ¬ν•œ μž¬κ·€ ꡬ쑰λ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” κ²½μš°μ—λŠ” 점화식(recurrence equation)을 ν†΅ν•˜μ—¬ ν‘œν˜„ν•  수 μžˆλ‹€.

λ§Œμ•½, μž…λ ₯ 크기 n이 μ–΄λŠ μˆ˜μ€€(c) μ΄ν•˜λ‘œ κ·Ήλ„λ‘œ μž‘μ•„μ§€λ©΄, 거의 μƒμˆ˜ μ‹œκ°„($O(1)$) μ•ˆμ— ν’€λ¦°λ‹€κ³  λ³Ό 수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄, λ°°μ—΄μ˜ μ›μ†Œκ°€ ν•˜λ‚˜λ§Œ μžˆλ‹€λ©΄ 정렬을 ν•˜μ§€ μ•Šκ³ ,μ•„λž˜μ— μ„€λͺ…ν•  A λ°°μ—΄λ‘œ Combine ν•˜λŠ” μ‹œκ°„λ§Œ μ‘΄μž¬ν•˜λ―€λ‘œ, μƒμˆ˜μ‹œκ°„μ— 풀릴 것이닀. μ΄λ•Œ, 단 1개짜리 배열을 Combineν•˜λŠ”λ° κ±Έλ¦¬λŠ” μƒμˆ˜μ‹œκ°„μ„ $c_1$라고 ν•˜μž.

μ΄μ™Έμ—λŠ” λ¨Όμ € 배열을 절반으둜 λ‚˜λˆ„λŠ”λ° $D(n)$ 만큼의 μ‹œκ°„μ΄ ν•„μš”ν•˜κ³ , 보톡 λ°°μ—΄μ˜ 크기와 관계없이 μƒμˆ˜ μ‹œκ°„μ΄ κ±Έλ¦°λ‹€. $D(n)=O(1)$ (Divide κ³Όμ •)

절반의 배열을 μ •λ ¬ν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ„, 두 λΆ€λΆ„λ°°μ—΄λ‘œ λ‚˜λˆ„μ–΄ μ²˜λ¦¬ν•˜λ―€λ‘œ, $2T(n/2)$만큼의 μ •λ ¬ μ‹œκ°„μ΄ ν•„μš”ν•˜λ‹€.(Conquer κ³Όμ •)

λ§ˆμ§€λ§‰μœΌλ‘œ 이 λ‘˜μ„ μœ„μ˜ Merge ν•¨μˆ˜μ²˜λŸΌ ν•˜λ‚˜λ‘œ ν•©ν•˜λŠ”λ°, $C(n)$ 만큼의 μ‹œκ°„μ΄ ν•„μš”ν•˜λ‹€.(Combine κ³Όμ •) μ΄λ•Œ, μœ„μ˜ Merge ν•¨μˆ˜ λ•Œ μ„€λͺ…ν•œ 것 처럼 $O(n)$의 μ‹œκ°„μ΄ 걸리며, μœ„μ˜ 1개짜리 배열을 Combined ν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ„ $c_1$이라 ν•˜μ˜€μœΌλ―€λ‘œ, 이에 λΉ„λ‘€ν•΄ $nc_1$이라 ν•  수 μžˆλ‹€.

μœ„ 경우λ₯Ό μ‹μœΌλ‘œ μ •λ¦¬ν•˜λ©΄ μ•„λž˜μ™€ 같은 점화식이 λ‚˜μ˜¨λ‹€.

\[T(n)=\left\{\begin{matrix} O(1),when\ n\leq c \\ D(n)+2T(n/2)+C(n) \end{matrix}\right.=\left\{\begin{matrix} c_1,when\ n = 1 \\ 2T(n/2)+nc_1 \end{matrix}\right.\]

μ΄λ•Œ $T(n/2)$λŠ” λ˜ν•œ λ‹€μŒκ³Ό 같이 ν‘œν˜„λ  수 μžˆλ‹€.

\[T(n/2)=\left\{\begin{matrix} O(1),when\ n\leq c \\ D(n/2)+2T(n/4)+C(n/2) \end{matrix}\right.=\left\{\begin{matrix} c_1,when\ n = 1 \\ 2T(n/4)+\frac{n}{2}\cdot c_1 \end{matrix}\right.\]

이λ₯Ό λŒ€μž…ν•˜κ³ , n은 1보닀 크닀고 κ°€μ •ν•˜λ©΄ $\eqref{eq:T(n)}$ 즉, $T(n)$은 λ‹€μŒκ³Ό 같이 정리 λœλ‹€.
\(T(n)=4T(n/4)+ 2nc_1\)
이런 μ‹μœΌλ‘œ $T(n)$을 계속 더 μž‘μ€ μž…λ ₯ κ°’μ˜ T ν•¨μˆ˜λ‘œ λ‚˜λˆ„λ‹€ 보면 μ•„λž˜ κ·Έλ¦Ό Figure 2와 같은 μž¬κ·€ 트리 ꡬ쑰가 λ‚˜μ˜€κ²Œ λœλ‹€.

μ΄λŸ¬ν•œ 트리 κ΅¬μ‘°λŠ” μƒκΈ°ν•œ κ·Έλ¦Όκ³Ό 같이 n의 크기가 1이 λ˜μ–΄ μƒμˆ˜μ‹œκ°„μ΄ λ‚˜μ˜¬ λ•ŒκΉŒμ§€ μ§„ν–‰λ˜λŠ”λ°, μ΄λŸ¬ν•œ μΈ΅ κ΅¬μ‘°λŠ” 총 $\log n + 1$ 개 만큼 μƒμ„±λœλ‹€. (컴퓨터 κ³΅ν•™μ—μ„œμ˜ $\log$의 밑은 μƒλž΅λ  μ‹œ κΈ°λ³Έ 2 μž„.)

그리고 각 μΈ΅ κ΅¬μ‘°μ—μ„œ k 갈래둜 μƒμ„±λœ λΉ„μš© $cn/k$은 λͺ¨λ‘ ν•©ν•˜λ©΄ μ–Έμ œλ‚˜ $cn$으둜 μΌμ •ν•˜λ―€λ‘œ, 각 μΈ΅μ—μ„œμ˜ μ‹œκ°„ λΉ„μš©μ€ $cn$이라고 ν•  수 μžˆλ‹€.

전체 μ•Œκ³ λ¦¬μ¦˜μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” $(\log n+1)cn = cn\log n + cn$이 되며, 이λ₯Ό λΉ…μ˜€ ν‘œκΈ°λ²•μœΌλ‘œ λ‚˜νƒ€λ‹ˆλ©΄ μ°¨μˆ˜μ™€ μƒμˆ˜κ°€ λ–¨μ–΄μ§€λ―€λ‘œ μ΅œμ’…μ μœΌλ‘œ 병렬 μ •λ ¬μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” $O(\log n)$이 λœλ‹€.