ํ๊ฐ๊ธฐ๋ฉฐ ํ๊ธฐํด์ ๋ด ๋ด์ ํฌ์ธํธ๋ผ๊ณ ๋จ๊ธด... ๋ค์ ์ฃผ๊ด... ๋ง์ด ์ฃผ๊ด์ ์ธ ์ ๋ฆฌ
Section 0 ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ (OOP) ๊ฐ๋
- Class
object's data fields, methods. ๋ญ ํจ์๋ ๋ฐ์ดํฐ ์ ์ํ๋ ๊ณณ
- Object
class's instance ์ 'fields'์ ์ ์ํ ๊ฒ
- Encapsulation
- Inheritance
๋ง ๊ทธ๋๋ก ์์. ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ์ํด์ ex) Tesla extends car
- Polymorphism
Overloading: ํด๋์ค ์ ๊ฐ์ ์ด๋ฆ์ธ๋ฐ ๋ค๋ฅด๊ฒ ์ฐ์ผ ๋,
Overriding: ๊ฐ์ ํจ์์ธ๋ ๋ค๋ฅธ ํด๋์ค์์ ์ฐ์ผ ๋
์ ๋งํ์
จ๋ค ๊ทผ๋ฐ ์๋ฐ ๋ค ๊น๋จน์ ใ
ใ
;
- Abstraction
์ด๊ฒ ์ด์ง ์ดํดํ ๊ฒ ๋ง๋ ์ง ๋ชจ๋ฅด๊ฒ ์ผ๋
( ๊ฐ์ํด๋์ค() ) ์ด๋ฐ ์์ผ๋ก ๊ฐ์์ concept? ํ์ ์ก์์ฃผ์ด์ผ
๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ์ฝ๋ ๊ณต์ ์ ๊ณ ์ ํ๊ฒ ์ฌ์ฉํ ์ ์๋ค !
ex) car(start() stop()) -> Tesla (start() stop())
Section 1 Big-O notation ๋น
์คํ๊ธฐ๋ฒ
๋ถ๋ช
์ด๊ฒ๋ ํ๊ต์์ ๋ฐฐ์ ๋๋ฐ ๊ธฐ์ต์ด ์๋๋ฒ๋ฆฌ๋ ๋ง๋ฒ..
์ฝ๋์ ํจ์จ์ฑ, ์๊ณ ๋ฆฌ์ฆ์ performance๋ฅผ ํํํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
* nO(1) = O(1) ๋ค์๊ณผ ๊ฐ์ n์ ์๊ณ ๋ฆฌ์ฆ์ ํฌ๊ฒ ์ํฅ์ฃผ์ง ์๋๋ค๋ ๊ฒ์ ์ฐธ๊ณ
- O(1) : order 1 : ํ๋์ ์ ๊ทผ. ex) push, pop, hash
- O(log n) : ex) Binary Search Tree Access, Search, Insertion, Deletion ์ด์งํ์ํธ๋ฆฌ..
์ผ์ฝ ..n=8, log 8 = log2^3 => 3 - O(n) : ex) traverse(์ํ) tree, linked list ๋ฆฌ์คํธ ๊ฐ์ ๊ฑฐ ์ ์ฒด ๋ค ๋๋ค !
- O(n log n) : ex) Quick sort, Merge sort, Heap sort
- O(n^2) : ํจ์์์ ํจ์. ex) Insertion sort, Bubble sort, Selection sort
Section 2 Sort
sort๋ ์๋ฌด๋๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด์ ์ดํดํ๋ ๊ฒ ํธํ ๋ฏํ๋ค, ํน์ ๊ทธ๋ฆผ?
https://github.com/minsuk-heo/problemsolving/tree/master/sort
- Bubble Sort
performance - O(n^2) / space complexity O(n)
์ธ์ item swap์ผ๋ก sort.
์๋ก ์ธ์ ํ ๋ ์์๋ฅผ ๊ฒ์ฌํ์ฌ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ
์ธ์ ํ 2๊ฐ์ ๋ ์ฝ๋๋ฅผ ๋น๊ตํ์ฌ ํฌ๊ธฐ๊ฐ ์์๋๋ก ๋์ด ์์ง ์์ผ๋ฉด ์๋ก ๊ตํํ๋ค.
์ ํ ์ ๋ ฌ๊ณผ ๊ธฐ๋ณธ ๊ฐ๋
์ด ์ ์ฌํ๋ค.
import unittest
def bubblesort(alist):
for i in range(len(alist)-1):
for j in range(len(alist)-1):
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
return alist
class unit_test(unittest.TestCase):
def test(self):
self.assertEqual([1, 2, 3, 4, 5, 6], bubblesort([4, 6, 1, 3, 5, 2]))
self.assertEqual([1, 2, 3, 4, 5, 6], bubblesort([6, 4, 3, 1, 2, 5]))
self.assertEqual([1, 2, 3, 4, 5, 6], bubblesort([6, 5, 4, 3, 2, 1]))
- Selection Sort
O(n^2) / minimum value ๊ฐ ํ์ํ๋ค. ์๋ฆฌ๋ง๋ค ํ๋์ฉ ๋น๊ตํ๋ฉด์ swaping
์ ์๋ฆฌ ์ ๋ ฌ(in-place sorting) ์๊ณ ๋ฆฌ์ฆ์ ํ๋
์ฒซ ๋ฒ์งธ ์์์๋ ์ฒซ ๋ฒ์งธ ์์น์ ๊ฐ์ฅ ์ต์๊ฐ์ ๋ฃ๋๋ค.
๋ ๋ฒ์งธ ์์์๋ ๋ ๋ฒ์งธ ์์น์ ๋จ์ ๊ฐ ์ค์์์ ์ต์๊ฐ์ ๋ฃ๋๋ค.
import unittest
def selectionSort(input):
for i in range(len(input) - 1):
# assume the min is the first element
idx_min = i
j = i + 1
# test against elements after i to find the smallest
while j < len(input):
if(input[j] < input[idx_min]):
# found new minimum; remember its index
idx_min = j
j = j + 1
if idx_min is not i:
# swap
input[idx_min], input[i] = input[i], input[idx_min]
return input
class unit_test(unittest.TestCase):
def test(self):
self.assertEqual([1, 2, 3, 4, 5, 6], selectionSort([4, 6, 1, 3, 5, 2]))
self.assertEqual([1, 2, 3, 4, 5, 6], selectionSort([6, 4, 3, 1, 2, 5]))
self.assertEqual([1, 2, 3, 4, 5, 6], selectionSort([6, 5, 4, 3, 2, 1]))
- Insertion Sort
๊ฐ๋จํ๋ฐ ํจ์จ์ฑ์ ๋จ์ด์ง๋.. ๋น๊ตํ๊ณ ์๋ณด๋ค ๋ ์์ผ๋ฉด swap... swap...
์ฝ์
์ ๋ ฌ์ ๋ ๋ฒ์งธ ์๋ฃ๋ถํฐ ์์ํ์ฌ ๊ทธ ์(์ผ์ชฝ)์ ์๋ฃ๋ค๊ณผ ๋น๊ตํ์ฌ ์ฝ์
ํ ์์น๋ฅผ ์ง์ ํ ํ ์๋ฃ๋ฅผ ๋ค๋ก ์ฎ๊ธฐ๊ณ ์ง์ ํ ์๋ฆฌ์ ์๋ฃ๋ฅผ ์ฝ์
ํ์ฌ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
์ฆ, ๋ ๋ฒ์งธ ์๋ฃ๋ ์ฒซ ๋ฒ์งธ ์๋ฃ, ์ธ ๋ฒ์งธ ์๋ฃ๋ ๋ ๋ฒ์งธ์ ์ฒซ ๋ฒ์งธ ์๋ฃ, ๋ค ๋ฒ์งธ ์๋ฃ๋ ์ธ ๋ฒ์งธ, ๋ ๋ฒ์งธ, ์ฒซ ๋ฒ์งธ ์๋ฃ์ ๋น๊ตํ ํ ์๋ฃ๊ฐ ์ฝ์
๋ ์์น๋ฅผ ์ฐพ๋๋ค. ์๋ฃ๊ฐ ์ฝ์
๋ ์์น๋ฅผ ์ฐพ์๋ค๋ฉด ๊ทธ ์์น์ ์๋ฃ๋ฅผ ์ฝ์
ํ๊ธฐ ์ํด ์๋ฃ๋ฅผ ํ ์นธ์ฉ ๋ค๋ก ์ด๋์ํจ๋ค.
์ฒ์ Key ๊ฐ์ ๋ ๋ฒ์งธ ์๋ฃ๋ถํฐ ์์ํ๋ค.
import unittest
def insertion_sort(input):
for idx, valueToInsert in enumerate(input):
# select the hole position where number is to be inserted
holePosition = idx
# check if previous no. is larger than value to be inserted
while holePosition > 0 and input[holePosition-1] > valueToInsert:
input[holePosition - 1], input[holePosition] = input[holePosition], input[holePosition-1]
holePosition = holePosition - 1
return input
class unit_test(unittest.TestCase):
def test(self):
self.assertEqual([1, 2, 3, 4, 5, 6], insertion_sort([4, 6, 1, 3, 5, 2]))
self.assertEqual([1, 2, 3, 4, 5, 6], insertion_sort([6, 4, 3, 1, 2, 5]))
self.assertEqual([1, 2, 3, 4, 5, 6], insertion_sort([6, 5, 4, 3, 2, 1]))
- Merge Sort
O(nlogn) / O(n) 8->4,4->2,2->1,1 ์์ ์ชผ๊ฐ์ ์ ๋ ฌํ๊ณ ํฉ์ณํฉ์ณ
์ด๊ฑด ๋ง๋ณด๋ค ๊ทธ๋ฆผ์ด ์ดํดํ๊ธฐ ํธํ
__author__ = 'Minsuk Heo'
def mergeSort(alist):
print("Splitting ",alist)
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
alist[k]=lefthalf[i]
i=i+1
else:
alist[k]=righthalf[j]
j=j+1
k=k+1
while i < len(lefthalf):
alist[k]=lefthalf[i]
i=i+1
k=k+1
while j < len(righthalf):
alist[k]=righthalf[j]
j=j+1
k=k+1
print("Merging ",alist)
alist = [6,2,4,1,3,7,5,8]
mergeSort(alist)
print(alist)
- Quick Sort
O(nlogn) (worst : O(n^2)) / O(n) ํจ์จ๋ฉด์์ good
Pivot(๊ฐ์ฅ ๋ง์ง๋ง์ ์ฌ์ฉ)์ ์ง์ ํด์ ๋น๊ตํด๊ฐ๋ค. ์์ผ๋ฉด ์ผ์ผ๋ก ์ด๋! ํฌ๋ฉด ์ฐ๋ก ์ด๋! ๋๋ฌ์ผ๋ฉด pivot ๋ค์ ์ง์ !
import unittest
def quick_sort(list, start, end):
# repeat until sublist has one item
# because the algorithm is using in-place space, we can not use len(list) instead we use start, end for sublist
if start < end:
# get pivot using partition method
pivot = partition(list, start, end)
# recurse quick sort left side from pivot
quick_sort(list, start, pivot-1)
# recurse quick sort right side from pivot
quick_sort(list,pivot+1, end)
return list
def partition(list, start, end):
# use end item as initial pivot
pivot = end
# use start as initial wall index
wall = start
left = start
# repeat until left item hit the end of list
while left < pivot:
# if left item is smaller than pivot, swap left item with wall and move wall to right
# this will ensure items smaller than pivot stay left side from the wall and
# the items greater than pivot stay right side from the wall
if list[left] < list[pivot]:
list[wall], list[left] = list[left], list[wall]
wall = wall + 1
left = left + 1
# when left hit the end of list, swap pivot with wall
list[wall], list[pivot] = list[pivot], list[wall]
# now left side of wall are the items smaller than wall
# now right side of pivot are the items greater than wall
# wall is the new pivot
pivot = wall
return pivot
class unit_test(unittest.TestCase):
def test(self):
list = [8, 13, 2, 6, 1, 4]
self.assertEqual([1, 2, 4, 6, 8, 13], quick_sort(list,0,len(list)-1))
list = [8, 1, 2, 5, 10, 14, 7, 21]
self.assertEqual([1, 2, 5, 7, 8, 10, 14, 21], quick_sort(list, 0, len(list) - 1))