๐ Python์ sort()์ ํ์ํธ(Timsort) ์ ๋ฆฌ
๐ฏ ์ ๋ ฌ(Sort)์ด๋?
์ ๋ ฌ์ ๋ฐ์ดํฐ๋ฅผ ์ผ์ ํ ์์(์ค๋ฆ์ฐจ์, ๋ด๋ฆผ์ฐจ์ ๋ฑ)๋ก ๋์ดํ๋ ์์
์ด๋ค.
์ ๋ ฌ๋ ๋ฐ์ดํฐ๋ ์ด์ง ํ์ ๋ฑ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ ํ์ฉ์ด ๊ฐ๋ฅํด์ง๋ฏ๋ก, ์ปดํจํฐ ๊ณผํ์์ ๋งค์ฐ ์ค์ํ ๋ฌธ์ ๋ค.
โ๏ธ ์ ๋ ฌ์ ์์ ์ฑ (Stability)
- ์์ ์ ๋ ฌ (Stable Sort) ๐ข
- ๋์ผํ ๊ฐ์ ๊ฐ์ง ๋ฐ์ดํฐ์ ์๋ ์ ๋ ฅ ์์๊ฐ ์ ์ง๋๋ ์ ๋ ฌ์ด๋ค.
- (์: ๋ณํฉ์ ๋ ฌ, ๋ฒ๋ธ์ ๋ ฌ, ์ฝ์ ์ ๋ ฌ)
- ๋ถ์์ ์ ๋ ฌ (Unstable Sort) ๐ด
- ๋์ผํ ๊ฐ์ ์ ๋ ฅ ์์๊ฐ ๋ณด์ฅ๋์ง ์๋ ์ ๋ ฌ์ด๋ค.
- (์: ํต์ ๋ ฌ, ํ์ ๋ ฌ, ์ ํ์ ๋ ฌ)
๐ ์ฃผ์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ ์์ฝ
์ ๋ ฌ ๋ฐฉ์ | ์๊ฐ๋ณต์ก๋(ํ๊ท ) | ์์ ์ฑ | ํน์ง ๋ฐ ์ค๋ช |
---|---|---|---|
๋ฒ๋ธ ์ ๋ ฌ |
O(nยฒ) | ๐ข ์์ | ์ธ์ ํ ์์๋ฅผ ๋ฐ๋ณต ๋น๊ต ๋ฐ ๊ตํ |
์ ํ ์ ๋ ฌ |
O(nยฒ) | ๐ด ๋ถ์์ | ์ต์๊ฐ(๋๋ ์ต๋๊ฐ) ์ ํ ํ ๊ตํ |
์ฝ์
์ ๋ ฌ |
O(nยฒ) | ๐ข ์์ | ์ด๋ฏธ ์ ๋ ฌ๋ ๋ถ๋ถ์ ์ฝ์ |
๋ณํฉ ์ ๋ ฌ |
O(n log n) | ๐ข ์์ | ๋ถํ ์ ๋ณต, ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ํ์ |
ํ ์ ๋ ฌ |
O(n log n) | ๐ด ๋ถ์์ | ํ ์๋ฃ๊ตฌ์กฐ ์ฌ์ฉ, ์ ์๋ฆฌ ์ ๋ ฌ |
ํต ์ ๋ ฌ |
O(n log n) | ๐ด ๋ถ์์ | ํผ๋ฒ ๊ธฐ์ค ๋ถํ , ํ๊ท ์ ์ผ๋ก ๋น ๋ฆ |
๐ ํ์ด์ฌ์ ๊ธฐ๋ณธ ์ ๋ ฌ: ํ์ํธ(Timsort)
ํ์ด์ฌ์ list.sort()
์ sorted()
ํจ์๋ ํ์ํธ(Timsort) ๋ผ๋ ํ์ด๋ธ๋ฆฌ๋ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ค.
๐ค ํ์ํธ(Timsort)๋?
- Tim Peters๊ฐ 2002๋ ํ์ด์ฌ์ ์ํด ์ค๊ณํ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
- ๋ณํฉ์ ๋ ฌ(Merge Sort) ๊ณผ ์ฝ์ ์ ๋ ฌ(Insertion Sort) ๋ฅผ ๊ฒฐํฉํ ํ์ด๋ธ๋ฆฌ๋ ๋ฐฉ์์ด๋ค.
- ์ค์ ๋ฐ์ดํฐ๊ฐ ๋ถ๋ถ์ ์ผ๋ก ์ด๋ฏธ ์ ๋ ฌ๋์ด ์๋ ๊ฒฝ์ฐ ๋งค์ฐ ๋น ๋ฅธ ์ฑ๋ฅ์ ๋ณด์ธ๋ค.
- ํ์ด์ฌ, Java SE 7, Android, Swift ๋ฑ ๋ค์ํ ์ธ์ด์์ ํ์ค ์ ๋ ฌ๋ก ์ฑํ๋์๋ค.
โ๏ธ ๋์ ์๋ฆฌ
- ๋ฐ(Run) ๋ถํ
- ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ต์ run ํฌ๊ธฐ(min_run, ๋ณดํต 32 ๋๋ 64) ๋ก ์๋ผ ๊ฐ ๊ตฌ๊ฐ(run)์ด ์ด๋ฏธ ์ ๋ ฌ๋์ด ์๊ฑฐ๋, ์ฝ์ ์ ๋ ฌ๋ก ๋น ๋ฅด๊ฒ ์ ๋ ฌ๋ ์ ์๋๋ก ํ๋ค.
- ๋ฐ ๋ณํฉ
- ์ ๋ ฌ๋ run๋ค์ ๋ณํฉ์ ๋ ฌ ๋ฐฉ์์ผ๋ก ํฉ์น๋ค.
- ๋ณํฉ ์, ์คํ์ ์์ธ run์ ํฌ๊ธฐ ๋น์จ์ ์กฐ์ ํด
๊ท ํ์กํ ๋ณํฉ๊ณผ ์์ ์ฑ์ ํ๋ณดํ๋ค.
- ๊ฐค๋กํ(Galloping) ๋ชจ๋
- ๋ณํฉ ๊ณผ์ ์์ ํ run์ ๊ฐ์ด ์ฐ์์ ์ผ๋ก ์ ํ๋๋ ๊ฒฝ์ฐ,
์ด์ง ํ์์ ํ์ฉํด ๋๋์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ๋ณํฉํ์ฌ ํจ์จ์ ๋์ธ๋ค.
- ๋ณํฉ ๊ณผ์ ์์ ํ run์ ๊ฐ์ด ์ฐ์์ ์ผ๋ก ์ ํ๋๋ ๊ฒฝ์ฐ,
โจ ํ์ํธ์ ์ฃผ์ ํน์ง
- ์์ ์ ๋ ฌ: ๋์ผํ ๊ฐ์ ์ ๋ ฅ ์์๊ฐ ๋ณด์กด๋๋ค.
- ์ต์ /ํ๊ท ์๊ฐ๋ณต์ก๋: O(n log n)
- ๋ถ๋ถ์ ์ผ๋ก ์ ๋ ฌ๋ ๋ฐ์ดํฐ์์ ๋งค์ฐ ๋น ๋ฅด๋ค.
- ์ค์ ๋ฐ์ดํฐ์ ํจํด(์์ฐ์ค๋ฌ์ด ์ ๋ ฌ ๊ตฌ๊ฐ)์ ์ต๋ํ ํ์ฉํ๋ค.
๐ ํ์ํธ์ ํต์ฌ ์ต์ ํ
- Run ํ์ง ๋ฐ ํ์ฅ: ์ด๋ฏธ ์ ๋ ฌ๋ ๊ตฌ๊ฐ(run)์ ์๋์ผ๋ก ์ธ์ํ๊ณ ,
run์ ๊ธธ์ด๊ฐ min_run๋ณด๋ค ์งง์ผ๋ฉด ์ฝ์ ์ ๋ ฌ๋ก ํ์ฅํ๋ค. - ์คํ ๊ธฐ๋ฐ ๋ณํฉ ๊ท์น:
๋ณํฉํ run์ ํฌ๊ธฐ ๋น์จ์ ์๊ฒฉํ ๊ด๋ฆฌํด
๋ณํฉ ํ์๋ฅผ ์ต์ํํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ์บ์ ํจ์จ์ ๋์ธ๋ค. - ๊ฐค๋กํ(Galloping) ๊ธฐ๋ฒ:
ํ์ชฝ run์์ ์ฐ์์ ์ผ๋ก ๋ง์ ๊ฐ์ด ์ ํ๋๋ฉด,
์ด์ง ํ์์ผ๋ก ๋ณํฉ ์๋๋ฅผ ๊ฐ์ํํ๋ค.
๐ ํ์ํธ์ ๋์ ์์ (๊ฐ๋จ ์์ฝ)
- ๋ฆฌ์คํธ๋ฅผ
min_run
ํฌ๊ธฐ๋ก ๋ถํ ํ๋ค. - ๊ฐ run์ ์ฝ์ ์ ๋ ฌ๋ก ์ ๋ ฌํ๋ค.
- ์ธ์ ํ run๋ค์ ๋ณํฉ์ ๋ ฌ ๋ฐฉ์์ผ๋ก ํฉ์น๋ค.
- ๋ชจ๋ run์ด ํ๋๋ก ํฉ์ณ์ง ๋๊น์ง ๋ฐ๋ณตํ๋ค.
๐ป ํ์ด์ฌ์์ ํ์ํธ ์ฌ์ฉ ์์
numbers = [5, 3, 8, 6, 2]
numbers.sort() # ๋ด๋ถ์ ์ผ๋ก ํ์ํธ ์ฌ์ฉ
print(numbers) # [2, 3, 5, 6, 8]
๐ ์ฐธ๊ณ : ํ์ํธ ๊ตฌํ์ ํต์ฌ ์ฝ๋ ๊ตฌ์กฐ (์์ฌ์ฝ๋)
def timsort(arr):
min_run = 32
n = len(arr)
# 1. ๊ฐ run๋ง๋ค ์ฝ์
์ ๋ ฌ ์ํ
for start in range(0, n, min_run):
end = min(start + min_run - 1, n - 1)
insertion_sort(arr, start, end)
# 2. run ๋ณํฉ (๋ณํฉ์ ๋ ฌ ๋ฐฉ์)
size = min_run
while size < n:
for left in range(0, n, 2 * size):
mid = min(n - 1, left + size - 1)
right = min((left + 2 * size - 1), (n - 1))
merge(arr, left, mid, right)
size *= 2
โ ๏ธ ์ค์ ๊ตฌํ์ ํจ์ฌ ๋ณต์กํ๋ฉฐ, run์ ํ์ง, ์คํ ๊ด๋ฆฌ, galloping ๋ฑ ๋ค์ํ ์ต์ ํ๊ฐ ์ ์ฉ๋์ด ์๋ค.
โ ๋ง๋ฌด๋ฆฌ
ํ์ด์ฌ์ ๊ธฐ๋ณธ ์ ๋ ฌ์ด ์ด๋ ๊ฒ ๊น์ ์ต์ ํ๋ฅผ ๊ฑฐ์น ํ์ํธ๋ผ๋ ๊ฒ์ ์๊ณ ๋๋, ํ์์ ๋ฌด์ฌ์ฝ ์ฐ๋ sort()
๊ฐ ์๋กญ๊ฒ ๋ณด์๋ค. ์ญ์ ๊ธฐ๋ณธ๊ธฐ๊ฐ ์ค์ํ๋ค๋ ๊ฒ์ ๋ค์ ํ๋ฒ ๋๊ผ๋ค.
๐ ์ฐธ๊ณ ์๋ฃ
- Wikipedia: Timsort[3]
- GeeksforGeeks: Tim Sort in Python[2]
- Real Python: Sorting Algorithms in Python[5]
- skerritt.blog: Timsort โ the fastest sorting algorithm youโve never heard of[4]