Quick Sort์ ๋ถํ ์ ๋ณต(divide and conquer) ๋ฐฉ๋ฒ ์ ํตํด ์ฃผ์ด์ง ๋ฐฐ์ด์ ์ ๋ ฌํ๋ค.

๋ถ๋ถ ๋ฐฐ์ด์ ์ ๋ ฌํ๋ค. ๋ถ๋ถ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ ์ถฉ๋ถํ ์์ง ์์ผ๋ฉด ์ํ ํธ์ถ์ ์ด์ฉํ์ฌ ๋ค์ ๋ถํ ์ ๋ณต ๋ฐฉ๋ฒ์ ์ ์ฉํ๋ค.
์ ๋ ฅ ๋ฐฐ์ด์ ํผ๋ฒ์ ๊ธฐ์ค์ผ๋ก ๋น๊ท ๋ฑํ๊ฒ 2๊ฐ์ ๋ถ๋ถ ๋ฐฐ์ด (ํผ๋ฒ์ ์ค์ฌ์ผ๋ก ์ผ์ชฝ : ํผ๋ฒ๋ณด๋ค ์์ ์์๋ค, ์ค๋ฅธ์ชฝ : ํผ๋ฒ๋ณด๋ค ํฐ ์์๋ค) ๋ก ๋ถํ ํ๋ค.
# Partition function
def partition(arr, low, high):
# Choose the pivot
pivot = arr[high]
# Index of smaller element and indicates
# the right position of pivot found so far
i = low - 1
# Traverse arr[low..high] and move all smaller
# elements to the left side. Elements from low to
# i are smaller after every iteration
for j in range(low, high):
if arr[j] < pivot:
i += 1
swap(arr, i, j)
# Move pivot after smaller elements and
# return its position
swap(arr, i + 1, high)
return i + 1
# Swap function
def swap(arr, i, j):
arr[i], arr[j] = arr[j], arr[i]
# The QuickSort function implementation
def quickSort(arr, low, high):
if low < high:
# pi is the partition return index of pivot
pi = partition(arr, low, high)
# Recursion calls for smaller elements
# and greater or equals elements
quickSort(arr, low, pi - 1)
quickSort(arr, pi + 1, high)
# Main driver code
if __name__ == "__main__":
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr, 0, n - 1)
for val in arr:
print(val, end=" ")
def quick_sort(arr):
if len(arr) <= 1:
return arr # ์์๊ฐ ํ๋ ์ดํ์ด๋ฉด ์ ๋ ฌ๋ ์ํ์ด๋ฏ๋ก ๊ทธ๋๋ก ๋ฐํ
pivot = arr[len(arr) // 2] # ํผ๋ฒ ์ ํ (๊ฐ์ด๋ฐ ๊ฐ)
left = [x for x in arr if x < pivot] # ํผ๋ฒ๋ณด๋ค ์์ ๊ฐ๋ค
middle = [x for x in arr if x == pivot] # ํผ๋ฒ๊ณผ ๊ฐ์ ๊ฐ๋ค
right = [x for x in arr if x > pivot] # ํผ๋ฒ๋ณด๋ค ํฐ ๊ฐ๋ค
return quick_sort(left) + middle + quick_sort(right)
# ํ
์คํธ
arr = [3, 6, 8, 10, 1, 2, 1]
print(quick_sort(arr)) # [1, 1, 2, 3, 6, 8, 10]
์ฃผ์ด์ง ๋ฐฐ์ด ์์์ ๊ตํ(swap)์ ํตํด, ์ ๋ ฌ์ด ์ํ๋๋ฏ๋ก O(n)์ด๋ค.
๋ณํฉ ์ ๋ ฌ ์ ๋ถํ ์ ๋ณต ์ ๊ทผ๋ฒ ์ ๋ฐ๋ฅด๋ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค . ์ ๋ ฅ ๋ฐฐ์ด์ ๋ ์์ ํ์ ๋ฐฐ์ด๋ก ์ฌ๊ท์ ์ผ๋ก ๋๋๊ณ ํด๋น ํ์ ๋ฐฐ์ด์ ์ ๋ ฌํ ๋ค์ ๋ค์ ๋ณํฉํ์ฌ ์ ๋ ฌ๋ ๋ฐฐ์ด์ ์ป์ต๋๋ค.
๊ฐ๋จํ ๋งํด์, ๋ณํฉ ์ ๋ ฌ ํ๋ก์ธ์ค๋ ๋ฐฐ์ด์ ๋ ๊ฐ์ ๋ฐ์ผ๋ก ๋๋๊ณ , ๊ฐ ๋ฐ์ ์ ๋ ฌํ ๋ค์, ์ ๋ ฌ๋ ๋ฐ์ ๋ค์ ๋ณํฉํ๋ ๊ฒ์ ๋๋ค. ์ด ํ๋ก์ธ์ค๋ ์ ์ฒด ๋ฐฐ์ด์ด ์ ๋ ฌ๋ ๋๊น์ง ๋ฐ๋ณต๋ฉ๋๋ค.
-> ํต์ํธ์๋ ๋ฐ๋๋ก ์์ ์ ๋ ฌ์ ์ํจ,
-> ์์๋ฅผ ์ชผ๊ฐ ํ, ๋ค์ ํฉ๋ณ์ํค๋ฉด์ ์ ๋ ฌํด๋๊ฐ๋ ๋ฐฉ์์ผ๋ก, ์ชผ๊ฐ๋ ๋ฐฉ์์ ํต์ ๋ ฌ๊ณผ ์ ์ฌ

ํต์ ๋ ฌ : ์ฐ์ ํผ๋ฒ์ ํตํด ์ ๋ ฌ(partition) โ ์์ญ์ ์ชผ๊ฐฌ(quickSort)
ํฉ๋ณ์ ๋ ฌ : ์์ญ์ ์ชผ๊ฐค ์ ์์ ๋งํผ ์ชผ๊ฐฌ(mergeSort) โ ์ ๋ ฌ(merge)
์ด๋ฏธ ํฉ๋ณ์ ๋์์ด ๋๋ ๋ ์์ญ์ด ๊ฐ ์์ญ์ ๋ํด์ ์ ๋ ฌ์ด ๋์ด์๊ธฐ ๋๋ฌธ์ ๋จ์ํ ๋ ๋ฐฐ์ด์ ์์ฐจ์ ์ผ๋ก ๋น๊ตํ๋ฉด์ ์ ๋ ฌํ ์๊ฐ ์๋ค.
โ โ โ ํฉ๋ณ์ ๋ ฌ์ ์์ฐจ์ ์ธ ๋น๊ต๋ก ์ ๋ ฌ์ ์งํํ๋ฏ๋ก, LinkedList์ ์ ๋ ฌ์ด ํ์ํ ๋ ์ฌ์ฉํ๋ฉด ํจ์จ์ ์ด๋ค.โ โ โ
Q. LinkedList๋ฅผ ํต์ ๋ ฌ์ ์ฌ์ฉํด ์ ๋ ฌํ๋ฉด?
์ฑ๋ฅ์ด ์ข์ง ์์
ํต์ ๋ ฌ์, ์์ฐจ ์ ๊ทผ์ด ์๋ ์์ ์ ๊ทผ์ด๊ธฐ ๋๋ฌธ
LinkedList๋ ์ฝ์
, ์ญ์ ์ฐ์ฐ์์ ์ ์ฉํ์ง๋ง ์ ๊ทผ ์ฐ์ฐ์์๋ ๋นํจ์จ์ ์
๋ฐ๋ผ์ ์์๋ก ์ ๊ทผํ๋ ํต์ํธ๋ฅผ ํ์ฉํ๋ฉด ์ค๋ฒํค๋ ๋ฐ์์ด ์ฆ๊ฐํ๊ฒ ๋จ
๋ฐฐ์ด์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด์ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ง๋ง, LinkedList๋ Head๋ถํฐ ํ์ํด์ผ ํจ
๋ฐฐ์ด[O(1)] vs LinkedList[O(n)]
def merge(arr, left, mid, right):
n1 = mid - left + 1
n2 = right - mid
# Create temp arrays
L = [0] * n1
R = [0] * n2
# Copy data to temp arrays L[] and R[]
for i in range(n1):
L[i] = arr[left + i]
for j in range(n2):
R[j] = arr[mid + 1 + j]
i = 0 # Initial index of first subarray
j = 0 # Initial index of second subarray
k = left # Initial index of merged subarray
# Merge the temp arrays back
# into arr[left..right]
while i < n1 and j < n2:
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# Copy the remaining elements of L[],
# if there are any
while i < n1:
arr[k] = L[i]
i += 1
k += 1
# Copy the remaining elements of R[],
# if there are any
while j < n2:
arr[k] = R[j]
j += 1
k += 1
def merge_sort(arr, left, right):
if left < right:
mid = (left + right) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, mid, right)
def print_list(arr):
for i in arr:
print(i, end=" ")
print()
# Driver code
if __name__ == "__main__":
arr = [12, 11, 13, 5, 6, 7]
print("Given array is")
print_list(arr)
merge_sort(arr, 0, len(arr) - 1)
print("\nSorted array is")
print_list(arr)
def merge_sort(arr):
if len(arr) <= 1:
return arr # ๋ฆฌ์คํธ ํฌ๊ธฐ๊ฐ 1 ์ดํ์ด๋ฉด ์ ๋ ฌ ์๋ฃ
mid = len(arr) // 2
left = merge_sort(arr[:mid]) # ์ผ์ชฝ ๋ฐ ์ ๋ ฌ
right = merge_sort(arr[mid:]) # ์ค๋ฅธ์ชฝ ๋ฐ ์ ๋ ฌ
return merge(left, right) # ์ ๋ ฌ๋ ๋ ๋ฆฌ์คํธ๋ฅผ ๋ณํฉ
def merge(left, right):
sorted_arr = []
i = j = 0
while i < len(left) and j < len(right): # ๋ ๋ฆฌ์คํธ๋ฅผ ๋น๊ตํ๋ฉฐ ์ ๋ ฌ
if left[i] < right[j]:
sorted_arr.append(left[i])
i += 1
else:
sorted_arr.append(right[j])
j += 1
sorted_arr.extend(left[i:]) # ๋จ์ ์์ ์ถ๊ฐ
sorted_arr.extend(right[j:]) # ๋จ์ ์์ ์ถ๊ฐ
return sorted_arr
# ํ
์คํธ
arr = [3, 6, 8, 10, 1, 2, 1]
print(merge_sort(arr)) # [1, 1, 2, 3, 6, 8, 10]
O(n), ๋ณํฉ ์ค์ ์ฌ์ฉ๋๋ ์์ ๋ฐฐ์ด์ ์ํ ์ถ๊ฐ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค.
ํ ์ ๋ ฌ ์ ์ด์ง ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ ์ ๊ธฐ๋ฐํ ํ(Heap) ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋กํ ๋น๊ต ๊ธฐ๋ฐ ์ ๋ ฌ ๊ธฐ์ ์ ๋๋ค.
์ ํ ์ ๋ ฌ ์ ๋ํ ์ต์ ํ๋ก ๋ณผ ์ ์๋๋ฐ , ๋จผ์ ์ต๋(๋๋ ์ต์) ์์๋ฅผ ์ฐพ์์ ๋ง์ง๋ง(๋๋ ์ฒซ ๋ฒ์งธ) ์์์ ๋ฐ๊ฟ๋๋ค. ๋๋จธ์ง ์์์ ๋ํด์๋ ๊ฐ์ ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.
ํ ์ ๋ ฌ์์๋ ์ด์ง ํ์ ์ฌ์ฉํ์ฌ O(n) ๋์ O(Log n)์์ ์ต๋ ์์๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ด๋ํ ์ ์์ผ๋ฏ๋ก O(n Log n) ์๊ฐ ๋ณต์ก๋๋ฅผ ๋ฌ์ฑํฉ๋๋ค.
Q. ์์ ์ด์ง ํธ๋ฆฌ๋?
์ฝ์ ํ ๋ ์ผ์ชฝ๋ถํฐ ์ฐจ๋ก๋๋ก ์ถ๊ฐํ๋ ์ด์ง ํธ๋ฆฌ
1๋จ๊ณ: ๋ฐฐ์ด์ ์์ ํ ์ด์ง ํธ๋ฆฌ๋ก ์ทจ๊ธ

2๋จ๊ณ: ์ต๋ ํ ๊ตฌ์ถ
3๋จ๊ณ: ์ ๋ ฌ๋์ง ์์ ๋ฐฐ์ด์ ๋์ ๊ฐ์ฅ ํฐ ์์๋ฅผ ๋ฐฐ์นํ์ฌ ๋ฐฐ์ด์ ์ ๋ ฌํฉ๋๋ค.
ํ์ ํ๋์ ์์๋ง ๋จ์ ๋๊น์ง ์ด๋ฌํ ๋จ๊ณ๋ฅผ ๊ณ์ ๋ฐ๋ณตํด์ผ ํฉ๋๋ค.


# Python program for implementation of heap Sort
# To heapify a subtree rooted with node i
# which is an index in arr[].
def heapify(arr, n, i):
# Initialize largest as root
largest = i
# left index = 2*i + 1
l = 2 * i + 1
# right index = 2*i + 2
r = 2 * i + 2
# If left child is larger than root
if l < n and arr[l] > arr[largest]:
largest = l
# If right child is larger than largest so far
if r < n and arr[r] > arr[largest]:
largest = r
# If largest is not root
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i] # Swap
# Recursively heapify the affected sub-tree
heapify(arr, n, largest)
# Main function to do heap sort
def heapSort(arr):
n = len(arr)
# Build heap (rearrange array)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# One by one extract an element from heap
for i in range(n - 1, 0, -1):
# Move root to end
arr[0], arr[i] = arr[i], arr[0]
# Call max heapify on the reduced heap
heapify(arr, i, 0)
def printArray(arr):
for i in arr:
print(i, end=" ")
print()
# Driver's code
arr = [9, 4, 3, 8, 10, 2, 5]
heapSort(arr)
print("Sorted array is ")
printArray(arr)
def heap_sort(arr):
import heapq
heapq.heapify(arr) # ๋ฆฌ์คํธ๋ฅผ ์ต์ ํ์ผ๋ก ๋ณํ
return [heapq.heappop(arr) for _ in range(len(arr))] # ํ์์ ํ๋์ฉ ๊บผ๋ด ์ ๋ ฌ
# ํ
์คํธ
arr = [3, 6, 8, 10, 1, 2, 1]
print(heap_sort(arr)) # [1, 1, 2, 3, 6, 8, 10]
def heapify(arr, n, i):
largest = i # ๋ฃจํธ ๋
ธ๋
left = 2 * i + 1 # ์ผ์ชฝ ์์ ๋
ธ๋
right = 2 * i + 2 # ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋
# ์ผ์ชฝ ์์์ด ๋ฃจํธ๋ณด๋ค ํฌ๋ค๋ฉด
if left < n and arr[left] > arr[largest]:
largest = left
# ์ค๋ฅธ์ชฝ ์์์ด ํ์ฌ ์ต๋๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด
if right < n and arr[right] > arr[largest]:
largest = right
# ์ต๋๊ฐ์ด ๋ฃจํธ๊ฐ ์๋๋ผ๋ฉด ์ค์ ํ ๋ค์ ํ ์์ฑ์ ์ ์งํ๋๋ก ํธ์ถ
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest) # ์ฌ๊ท ํธ์ถ
def heap_sort(arr):
n = len(arr)
# 1. ์ต๋ ํ(Max Heap) ๋ง๋ค๊ธฐ (Heapify ๊ณผ์ )
for i in range(n // 2 - 1, -1, -1): # ๋ด๋ถ ๋
ธ๋๋ถํฐ ํ ์์ฑ์ ๋ง์กฑํ๋๋ก ๋ณํ
heapify(arr, n, i)
# 2. ์ ๋ ฌ ๊ณผ์ (Heap Sort)
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # ์ต๋๊ฐ(๋ฃจํธ)์ ๋ง์ง๋ง ์์๋ฅผ ๊ตํ
heapify(arr, i, 0) # ๋ฃจํธ์ ๋ํด ๋ค์ Heapify ์ํ
return arr
# ํ
์คํธ
arr = [3, 6, 8, 10, 1, 2, 1]
print(heap_sort(arr)) # [1, 1, 2, 3, 6, 8, 10]
-> ์ต์ ํ or ์ต๋ ํ์ ๋ฃจํธ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ํ๋ฒ์ ํ ๊ตฌ์ฑ์ ํตํด ๊ตฌํ๋ ๊ฒ์ด ๊ฐ๋ฅ
-> ์ฝ์ ์ ๋ ฌ๋ณด๋ค ๋์ฑ ๊ฐ์ ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ด๋ผ ์ ์์
- ๋น ๋ฅธ ์ ๋ ฌ์ด ํ์ํ๋ฉด? โ ํต ์ ๋ ฌ
- ์์ ์ ๋ ฌ์ด ํ์ํ๋ฉด? โ ๋ณํฉ ์ ๋ ฌ
- ์ ์๋ฆฌ ์ ๋ ฌ์ด ํ์ํ๋ฉด? โ ํ ์ ๋ ฌ
์ ๋ ฌ์๊ณ ๋ฆฌ์ฆ ํ๊ท ์๊ฐ ๋ณต์ก๋ ์ต์ ์๊ฐ ๋ณต์ก๋ ๊ณต๊ฐ ๋ณต์ก๋ ํน์ง
ํต ์ ๋ ฌ (Quick Sort) O(n log n) O(nยฒ) (์ต์ : ์ด๋ฏธ ์ ๋ ฌ๋ ๊ฒฝ์ฐ) O(n) (๋นํจ์จ์ ๊ตฌํ) ๋ถํ ์ ๋ณต, ๋น ๋ฆ
๋ณํฉ ์ ๋ ฌ (Merge Sort) O(n log n) O(n log n) O(n) ์์ ์ ๋ ฌ, ์ผ๊ด๋ ์ฑ๋ฅ
ํ ์ ๋ ฌ (Heap Sort) O(n log n) O(n log n) O(1) ์ ์๋ฆฌ ์ ๋ ฌ ๊ฐ๋ฅ