Quick sort๋ Divide and Conquer(๋ถํ ์ ๋ณต)
์๊ณ ๋ฆฌ์ฆ ์ข
๋ฅ์ค ํ๋์ด๋ค. ๋ถํ ์ ๋ณต์ด๋ ์ฃผ์ด์ง ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ sub ๋ฌธ์ ๋ค๋ก ๋๋ ๋ค์์ ๊ทธ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ ๋ค์์ ํฉ์น๋ ๊ฒ์ ์๋ฏธํ๋ค.
Pseudo-code ์ค๋ช
Quicksort๋ ์์์ ์ซ์๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ํ ๋ค์์ ๊ทธ ์ซ์๋ณด๋ค ์์ ์ซ์๋ค๊ณผ ํฐ ์ซ์๋ค์ ๋ค์ ์ฌ๊ท๋ฅผ ์ฌ์ฉํด์ quick sort ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํ๋ค. ๊ทธ๋ฌ๋ฉด ๋ค์ ๊ทธ ๋ถํ ๋ ์ซ์๋ค ์ค์์ ๊ธฐ์ค์ ์ ํ๊ณ ๋๋ ์ quick sort๋ฅผ ์งํํ๋ค. ์กฐ๊ธ ๋ ์์ธํ ์ค๋ช ํ๋ฉด, ์์์ ์ซ์๋ฅผ ๊ณ ๋ฅด๊ณ ๋์ ํด๋น ์ซ์๋ณด๋ค ์์ ์ซ์๋ค์ ์ผ์ชฝ์ ์์น์ํค๊ณ , ํด๋น ์ซ์๋ณด๋ค ํฐ ์ซ์๋ค์ ์ค๋ฅธ์ชฝ์ ์์น์ํจ๋ค. ๊ทธ๋ฌ๊ณ ๋์ ์ ํด์ง ์์์ ์ซ์๋ฅผ ๊ทธ ์ค๊ฐ์ ์์น์ํค๋ ๊ฒ์ด๋ค.
Partition
๋ถ๋ถ์ ์์ธํ ์ดํด๋ณด๊ธฐ ์ ์ ๊ฐ ์ธ์๋ค์ด ๋ฌด์์ ์๋ฏธํ๋์ง ๋ณด๋ ค๊ณ ํ๋ค. A
๋ ์ฃผ์ด์ง list์ด๋ค. p
๋ ์ฃผ์ด์ง list์ lower part๋ก list์ ์์ ๋ถ๋ถ์ ์๋ฏธํ๊ณ , r
์ ์ฃผ์ด์ง list์ higher part๋ก list์ ๋ ๋ถ๋ถ์ ์๋ฏธํ๋ค.
- pivot์ ์ ํ๋ค
- i๋ list์ ์์ index๋ณด๋ค ํ๋ ์๊ฒ ๋๋ค. i๋ pivot์ธ A[r]๋ณด๋ค ์์ ์ซ์๋ค์ list ์ค ๊ฐ์ฅ ๋์ index๋ฅผ ์๋ฏธํ๋ค.
-
j๋ ์ฃผ์ด์ง list์ ์์ ๋ถ๋ถ์ธ p๋ถํฐ ์์ํด์ r-1๊น์ง ๋ฐ๋ณตํ๋ค.
- item์ด pivot๋ณด๋ค ์์ผ๋ฉด i+=1์ ํด์ค๋ค. pivot๋ณด๋ค ์์ ์๋ค์ index ๋ฒ์๋ฅผ ๋๋ฆฌ๋ ์์ ์ด๋ค.
- ๊ทธ๋ฌ๊ณ ๋์ ์๋ก swap์ ํด์ค๋ค.
- ๋ง์ง๋ง์ pivot์ pivot๋ณด๋ค ์์ ์ ๊ทธ๋ฆฌ๊ณ ํฐ ์๋ค๋ก ๋๋ ๊ตฌ๊ฐ ์ค๊ฐ์ ์์น์ํจ๋ค.
- i+1, ์ฆ, pivot์ ์์น index๋ฅผ ๋ฆฌํดํ๋ค.
Quick sort๋ ์ถ๊ฐ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํ ๋น๋ list์ ๋ฉ๋ชจ๋ฆฌ๋ง ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ inplace
์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ถ๋ฆฐ๋ค. ๋ฌผ๋ก , ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ์ non-inplace ์๊ณ ๋ฆฌ์ฆ์ผ๋ก๋ ์์ฑ๋ ์ ์๋ค.
Quick sort ์๊ณ ๋ฆฌ์ฆ์ ํ๊ท ์๊ฐ ๋ณต์ก๋๋ O(nlgn)
์ด๋ค. Worse case๋ pivot์ผ๋ก ํญ์ list์ ๊ฐ์ฅ ์์ ๊ฐ ํน์ ๊ฐ์ฅ ํฐ ๊ฐ์ผ๋ก ์ ํ์ ๋ ๋ฐ์ํ๊ณ ๊ทธ ๋์ ์๊ฐ ๋ณต์ก๋๋ O(n^2)
๊ฐ ๋๋ค. ํ์ง๋ง, ๋ณดํต pivot์ ์ ํ ๋ ๋๋ค์ผ๋ก ์ ํ๊ธฐ ๋๋ฌธ์ ํ๊ท ์ ์ผ๋ก๋ ์๊ฐ๋ณต์ก๋๊ฐ O(nlgn)
์ด ๋๋ค.
source: studytonight-quick-sort
์ด์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด์ quick sort๊ฐ sorting์ ํ๋ ๊ณผ์ ์ ์ดํด๋ณด์. ํด๋น ๊ทธ๋ฆผ์ Iteration๋ง๋ค ๋ฐ๋๋ ๊ณผ์ ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด ์๋๋ผ ํ๋ฒ divide๋๊ณ conquer๋๋ ๊ณผ์ ์ ๋ณด์ฌ์ค๋ค. ๊ทธ๋ฆผ ๋ด 6๊ฐ์ ์์ ๊ทธ๋ฆผ๋ค์ด ์๋๋ฐ ๊ฐ๊ฐ step1~6์ผ๋ก ํํ์ ํ๋ ค๊ณ ํ๋ค.
- step1์์๋, pivot์ list[r]์ธ 6์ด ์ ํ๋์๋ค.
- step2์์๋, 6์ 3๋ฒ์งธ index์ ์์นํ๊ฒ ๋์๊ณ , ํด๋น index๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ index๋ค์ ๊ฐ๋ค์ 6๋ณด๋ค ์๊ณ , ์ค๋ฅธ์ชฝ์ 6๋ณด๋ค ํฌ๋ค. 6์ด ์๊ธฐ ์๋ฆฌ๋ฅผ ์ฐพ์๊ธฐ ๋๋ฌธ์ ์ ๋ ฌ๋์๋ค๊ณ ๊ฐ์ฃผ๋ฅผ ํ๋ค. ๊ทธ๋ฌ๊ณ ๋์ ์๋ก์ด pivot๋ค์ ์ ํํ๊ฒ ๋๊ณ , ์ซ์ 6์ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ list์ธ [2,3,5]์ ์ค๋ฅธ์ชฝ list์ธ [7,9,10,11,14,12]์์ ๊ฐ๊ฐ ์๋ก์ด pivot๋ค์ด ์ ํด์ก๋ค.
- step3์์๋, 3๊ณผ 11์ ์ ๋ ฌ๋ ์๋ฆฌ์ ์ด๋์ ์์ผฐ๋ค. ๊ทธ๋ฌ๊ณ ๋์ 3์ ์ข์ฐ list์์ ๊ฐ๊ฐ pivot(2,5)์ ๊ณ ๋ฅด๊ณ , 11์ ์ข์ฐ list์์ ๊ฐ๊ฐ pivot(10,12)์ ์ ํํ๋ค.
- ste4์์๋, 2์ 5๋ ๊ฐ๊ฐ ์์ ๋ค์ด p์ด์ r์ด๊ธฐ ๋๋ฌธ์ ์ ๋ ฌ๋ ์ํ๋ก ๊ฐ์ฃผ๋์๋ค. 10์ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ์ ์์ ๋ณด๋ค ํฐ ์ซ์๋ค์ด ์์ผ๋ ๊ทธ๋๋ก ์์น ์ด๋์ ์ํ๊ณ 12๋ ํ์นธ ์ด๋์ ํ๋ค. ๊ทธ๋ฌ๊ณ ๋์ ๋ค์ pivot(9,14)๋ฅผ ์ ํํ๋ค.
- step5์์๋, 9์ 14๋ฅผ ๋ ์์ง์ผ ๊ณณ์ด ์์๊ธฐ ๋๋ฌธ์ ์ ๋ ฌ๋ ์ํ๋ก ๊ฐ์ฃผํ๋ค. ๊ทธ๋ฌ๊ณ ๋ง์ง๋ง pivot์ผ๋ก ์ ํ๋์ง ์์๋, 7์ ์ ํํ๋ค.
- step6์์๋, 7์ด p์ด์ r์ด๊ธฐ ๋๋ฌธ์ ์ ๋ ฌ๋ ์ํ๋ก ๊ฐ์ฃผํ๊ฒ ๋๋ค. ์ด๋ ๊ฒ ๋๋ฉด, ์ ์ฒด list๊ฐ ์ ๋ ฌ์ด ๋๋ค.
์์์ QuickSort ์๊ณ ๋ฆฌ์ฆ์ ํธ์ถํ ๋ ํ์ํ ์ธ์๋ค์ ์๋ฏธ๋ ์ค๋ช
ํ๊ณ , ์ด์ ์ด๊ธฐ์ ์ด๋ค ๊ฐ์ ๋ฃ์ด์ผ ํ๋์ง ์ค๋ช
ํ๋ ค๊ณ ํ๋ค. A
์๋ฆฌ์๋ ์ ๋ ฌํด์ผํ list๋ฅผ ๋๊ธฐ๊ณ , p
์ ์๋ฆฌ์๋ list์ ์์ index, r
์๋ฆฌ์๋ list์ ๊ฐ์ฅ ๋ง์ง๋ง index๋ฅผ ์ ๋ฌํ๋ฉด ๋๋ค.
Python Code
import random
class QuickSort:
def __init__(self, num):
self.num = num
def quick_sort(self, p, r):
# p๋ list์์, r์ ๋, q๋ ์ค๊ฐ์ธ pivot
if p<r:
q = self.partition(p,r)
self.quick_sort(p,q-1) # pivot์ ์ผ์ชฝ์ ๋ค์ ๋ถํ ํ๋ค
self.quick_sort(q+1,r) # pivot์ ์ค๋ฅธ์ชฝ์ ๋ค์ ๋ถํ ํ๋ค
def partition(self, p, r):
x = self.num[r] # pivot ๊ฐ ์ ์ฅ
i = p - 1
for j in range(p, r):
if self.num[j] <= x: # pivot๋ณด๋ค ์์ผ๋ฉด ํด๋น ๊ฐ์ pivot index๋ณด๋ค ์ผ์ชฝ์ผ๋ก ์ด๋์ํจ๋ค
i += 1
self.num[i], self.num[j] = self.num[j] ,self.num[i]
self.num[i+1], self.num[r] = self.num[r], self.num[i+1] # pivot์ ์ ์ฒด list์ ์ ๋ ฌ๋ ์์น์ ๋๋๋ค
return i+1 # pivot์ ์์น๋ฅผ ๋ฆฌํดํ๋ค
number = [i for i in range(10)]
random.shuffle(number)
print(number)
quick = QuickSort(number)
quick.quick_sort(0, len(number)-1) # list์ ์ฒซ index์ ๊ฐ์ฅ ๋ง์ง๋ง index๋ฅผ ์ ๋ฌํ๋ค
print(quick.num)