이것이 μ½”λ”©ν…ŒμŠ€νŠΈλ‹€/μ •λ ¬

μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•˜μ—¬

CheonD 2020. 8. 26. 18:01

μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•˜μ—¬

 

 

μ •λ ¬

- 데이터λ₯Ό νŠΉμ •ν•œ 기쀀에 λ”°λΌμ„œ μˆœμ„œλŒ€λ‘œ λ‚˜μ—΄ν•˜λŠ” 것.

문제λ₯Ό ν’€κ±°λ‚˜, 무언가λ₯Ό κ΅¬ν˜„ν•  λ•Œ κ°€μž₯ μ€‘μš”ν•œ 것은 "μˆ˜ν–‰μ‹œκ°„"이닀. 이 μˆ˜ν–‰μ‹œκ°„μ€ 상황에 λ§žλŠ” μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•¨μœΌλ‘œμ¨ 쀄어든닀. 이에 μžˆμ–΄ "μ •λ ¬"은 μ•„μ£Ό μ€‘μš”ν•œ μš”μ†Œκ°€ λœλ‹€.

 

 

이 κΈ€μ—μ„œλŠ” λŒ€ν‘œμ μΈ μ •λ ¬ 3가지. 선택 μ •λ ¬, μ‚½μž… μ •λ ¬, 퀡 μ •λ ¬λ§Œμ„ μ•Œμ•„λ³Ό 것이닀.

 

선택 μ •λ ¬

-κ°€μž₯ μž‘μ€ 데이터λ₯Ό 선택해 맨 μ•žμ— μžˆλŠ” 데이터와 λ°”κΎΈκ³ , κ·Έ λ‹€μŒ μž‘μ€ 데이터λ₯Ό 선택해 λ‘λ²ˆμ§Έ 데이터와 λ°”κΎΈλŠ” μ•Œκ³ λ¦¬μ¦˜

 

λ°”λ‘œ μ˜ˆμ‹œλ‘œ λ„˜μ–΄κ°€λ³΄μž.

a = [3, 7, 0, 6] λΌλŠ” λ¦¬μŠ€νŠΈκ°€ μžˆλ‹€κ³  κ°€μ •ν•˜μž.

1. 0을 μ„ νƒν•΄μ„œ 3κ³Ό λ°”κΎΌλ‹€ -> [0, 7, 3 ,6]

2. 3을 μ„ νƒν•΄μ„œ 7κ³Ό λ°”κΎΌλ‹€ -> [0, 3, 7, 6]

3. 7을 μ„ νƒν•΄μ„œ 6κ³Ό λ°”κΎΌλ‹€ -> [0, 3, 6, 7]

 

이와같이 n개의 μˆ˜κ°€ μžˆμ„ λ•Œ n + n-1 + n-2---- +2κ°€ 되고, μ΄λŠ” μ‹œκ°„ λ³΅μž‘λ„ O(N^2)둜 λ³Ό 수 μžˆλ‹€.

데이터가 100개라면 μˆ˜ν–‰ μ‹œκ°„μ€ 10,000λ°° λŠ˜μ–΄λ‚˜λŠ” 것이닀. μ •λ ¬ μ•Œκ³ λ¦¬μ¦˜ μ€‘μ—μ„œ κ΅¬ν˜„ν•˜κΈ°λŠ” μ‰½μ§€λ§Œ, μƒλ‹Ήνžˆ λΉ„νš¨μœ¨μ μΈ μ•Œκ³ λ¦¬μ¦˜μ΄λΌκ³  λ³Ό 수 μžˆλ‹€. 

 

선택 μ •λ ¬ μ†ŒμŠ€μ½”λ“œ

array = [0,5,2,7,4]

for i in range(len(array)):
  min_index = i
  for j in range(i+1, len(array)):
    if array[min_index] > array[j] :
      min_index = j
    array[i], array[min_index] = array[min_index], array[i]
    
print(array)

 

 

 

μ‚½μž… μ •λ ¬

-νŠΉμ •ν•œ 데이터λ₯Ό μ μ ˆν•œ μœ„μΉ˜μ— 'μ‚½μž…'ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜

-선택 정렬에 λΉ„ν•΄ κ΅¬ν˜„μ€ μ–΄λ ΅μ§€λ§Œ, μ‹€ν–‰ μ‹œκ°„ μΈ‘λ©΄μ—μ„œ λ”μš± νš¨μœ¨μ μ΄λ‹€ 

-정렬이 λ˜μ–΄μžˆμ„ λ•Œ μ‹œκ°„ λ³΅μž‘λ„κ°€ O(N)이닀.

-μ‚½μž…μ •λ ¬μ—μ„œ μ²«λ²ˆμ§ΈλŠ” μ •λ ¬λ˜μ–΄ μžˆλ‹€κ³  νŒλ‹¨ν•˜κΈ° λ•Œλ¬Έμ— λ‘λ²ˆμ§ΈλΆ€ν„° μ‹œμž‘.

 

μ˜ˆμ‹œ

a = [7 5 9 3]

1. 5λŠ” 7보닀 μž‘κΈ°μ— λ‘˜μ„ swapν•œλ‹€.-->[5 7 9 3]

2. 9λŠ” 7보닀 ν¬κ²Œμ— κ°€λ§Œνžˆ λ‘”λ‹€.

3. 3은 9λΆ€ν„° μž‘κΈ°μ— swap ν•œλ‹€--> [5 7 3 9] --> 이λ₯Ό ν•œ 번 더 μˆ˜ν–‰ν•œλ‹€ -->[5 3 7 9] --> ν•œ 번 더 μˆ˜ν–‰ -->[3 5 7 9]

 

jλ₯Ό νƒμƒ‰ν•˜λŠ” 수라고 λ†“μ•˜μ„ λ•Œ, j-1보닀 μž‘λ‹€λ©΄ swap을 μ§„ν–‰ν•˜κ³  크닀면 breakλ₯Ό λ„£μ–΄μ£Όλ©΄ λœλ‹€.

 

μ‚½μž… μ •λ ¬ μ†ŒμŠ€μ½”λ“œ

array = [1,4,2,5,3,8]

for i in range(1,len(array)):
  for j in range(i, 0, -1):
    if array[j] < array[j-1] :
      array[j], array[j-1] = array[j-1], array[j]
    else :
      break
      
print(array)

 

퀡 μ •λ ¬

-κΈ°μ€€ 데이터λ₯Ό μ„€μ •ν•˜κ³  κ·Έ 기쀀보닀 큰 데이터와 μž‘μ€ λ°μ΄ν„°μ˜ μœ„μΉ˜λ₯Ό λ°”κΎΈλŠ” μ•Œκ³ λ¦¬μ¦˜

 

이 κΈ€μ—μ„œλŠ” λŒ€ν‘œμ μΈ λΆ„ν•  λ°©μ‹μœΌλ‘œ 퀡 정렬을 μ†Œκ°œν•  것이닀. 방법을 천천히 μ‚΄νŽ΄λ³΄μž

1. ν”Όλ²—(리슀트의 첫번째 숫자)λ₯Ό μ„€μ •ν•œλ‹€.

2. μ™Όμͺ½μ—μ„œλΆ€ν„° 피벗보닀 큰 데이터λ₯Ό μ°Ύκ³ , 였λ₯Έμͺ½μ—μ„œλΆ€ν„° 피벗보닀 μž‘μ€ 데이터λ₯Ό μ°ΎλŠ”λ‹€. 이λ₯Ό swapν•΄μ€€λ‹€. 

3. μ™Όμͺ½μ—μ„œ μ°ΎλŠ” 값이 였λ₯Έμͺ½μ—μ„œ μ°ΎλŠ”κ°’κ³Ό μ—‡κ°ˆλ Έμ„ λ•Œ 였λ₯Έμͺ½μ— μžˆλŠ” 값을 ν”Όλ²—κ³Ό λ°”κΏ”μ€€λ‹€λ©΄ 피벗을 κΈ°μ€€μœΌλ‘œ μ™Όμͺ½μ€ 피벗보닀 μž‘μ€ κ°’λ“€, 였λ₯Έμͺ½μ€ 피벗보닀 큰 κ°’λ“€λ‘œ 정렬이 λœλ‹€.

 

퀡 μ •λ ¬ μ†ŒμŠ€μ½”λ“œ

array = [3,4,1,5,2,3,5,7]

def quick_sort(array, start, end):
  if start >=end:
    return
  pivot = start
  left = start+1
  right = end
  while left <= right:
    while left <= end and array[left] <= array[pivot]:
      left+=1
    while right > start and array[right] >=array[pivot]:
      right-=1
    if left > right:
      array[pivot], array[right] = array[right], array[pivot]
    else :
      array[left], array[right] = array[right], array[left]
      quick_sort(array, start, right-1)
      quick_sort(array, right+1, end)

quick_sort(array,0,len(array)-1)
print(array)

νŒŒμ΄μ¬μ—μ„œλ§Œ κ°€λŠ₯ν•œ 퀡 μ •λ ¬ λ˜ν•œ μ‘΄μž¬ν•œλ‹€. μ΄λŠ” 기쑴의 퀡 μ •λ ¬λ³΄λ‹€λŠ” μ—°μ‚° νšŸμˆ˜κ°€ λ§Žμ§€λ§Œ 직관적이고 κ΅¬ν˜„κ°€κΈ°κ°€ 쉽닀. 

 

파이썬 μ „μš© μ†ŒμŠ€μ½”λ“œ

 

array = [2,3,1,4,9]

def quick_sort(array):
  if len(array) <=1:
    return array
  pivot = array[0]
  tail  = array[1:]
  
  left_side = [x for x in tail if x<=pivot]
  right_side = [x for x in tail if x>pivot]
  
  return quick_sort(left_side) + [pivot] + quick_sort(right_sort)
  
  print(quick_sort(array))

퀡 μ •λ ¬μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” N개의 데이터가 μ‘΄μž¬ν•œλ‹€λ©΄, Nλ²ˆλ™μ•ˆ μž‘μ€ 데이터와 큰 데이터λ₯Ό λ°”κΎΈκ³  이λ₯Ό λΆ„ν•  logN번 ν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€. 그렇기에 퀡 정렬은 N X logN의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό λ”°λ₯Έλ‹€. 이λ₯Ό μ§κ΄€μ μœΌλ‘œ μ΄ν•΄ν•˜λŠ” 것은 λ„“μ΄λ‘œ μ•Œ 수 μžˆλŠ”λ°, Nκ°œκ°€ κ°€λ‘œ, logN이 μ„Έλ‘œλΌκ³  봀을 λ•Œ λ‘κ°œκ°€ κ³±ν•œ κ²ƒλ§ŒνΌ μ—°μ‚°νšŸμˆ˜κ°€ 생긴닀. μ΄λŠ” 선택정렬과 μ‚½μž…μ •λ ¬μ— λΉ„ν•΄ κ·Ήλͺ…ν•œ 속도차이가 μžˆμŒμ„ μ•Œ 수 μžˆλ‹€. 퀡 정렬은 ν‰κ· μ μœΌλ‘œ O(NlogN)을 λ”°λ₯΄μ§€λ§Œ 데이터가 μ •λ ¬λ˜μ–΄ μžˆλŠ” 경우 맀우 느리게 λ™μž‘ν•  수 μžˆλ‹€. 바꾸지 μ•Šμ•„λ„ λ˜λŠ” 수λ₯Ό λ°”κΎΈκΈ° λ•Œλ¬Έμ΄λ‹€. μ΄λŠ” 선택정렬과 같이 O(N^2)인 κ²½μš°μ΄λ‹€.