이진 탐색(Binary Search)
이진 탐색과 순차 탐색의 비교
분할 정복 알고리즘과 이진 탐색
알고리즘 구현
예) 데이터가 [2, 3, 7, 12, 20] 일 때
- binary_search(data_list, find_data) 함수를 만듬
- data_list의 중간값을 find_data와 비교해서
- find_data < data_list의 중간값: 맨 앞부터 data_list의 중간까지 find_data를 찾음
- find_data > data_list의 중간값: data_list의 중간부터 맨 끝까지 data_data를 찾음
- 그렇지 않다면 data_list 중간값은 find_data로 일치
def binary_search(data, search):
print(data)
if len(data) == 1 and search == data[0]:
return True
if len(data) == 1 and search != data[0]:
return False
if len(data) == 0:
return False
medium = len(data) // 2
if search == data[medium]:
return True
else:
if search > data[medium]:
return binary_search(data[medium + 1:], search)
else:
return binary_search(data[:medium], search)
binary_search(data_list, 90)
[14, 33, 38, 40, 54, 63, 70, 89, 92, 97]
[70, 89, 92, 97]
[70, 89]
[]
False
알고리즘 분석
빅 오 표기법으로는 k+1의 결국 최종 시간 복잡도 O(𝑙𝑜𝑔𝑛)
그래프(Graph)
그래프 관련 용어
그래프 종류
그래프와 트리의 차이
그래프 | 트리 | |
---|---|---|
정의 | 노드와 노드를 연결하는 간선으로 표현되는 자료 구조 | 그래프의 한 종류, 방향성이 있는 비순환 그래프 |
방향성 | 방향 그래프, 무방향 그래프 둘다 존재함 | 방향 그래프만 존재함 |
사이클 | 사이클 가능함, 순환 및 비순환 그래프 모두 존재함 | 비순환 그래프로 사이클이 존재하지 않음 |
루트 노드 | 루트 노드 존재하지 않음 | 루트 노드 존재함 |
부모/자식 관계 | 부모 자식 개념이 존재하지 않음 | 부모 자식 관계가 존재함 |
BFS란?
BFS 알고리즘 구현
data.pop() # 스택 - 가장 나중에 넣은 데이터를 가장 먼저 꺼내는 구조 - 후입선출
data.pop(0) # 큐 - 가장 먼저 넣은 데이터를 가장 먼저 꺼내는 구조 - 선입선출
def bfs(graph, start_node):
visited, need_visit = list(), list()
need_visit.append(start_node)
while need_visit:
node = need_visit.pop(0)
if node not in visited:
visited.append(node)
need_visit.extend(graph[node])
return visited
깊이 우선 탐색(Depth_First Search)
def dfs(graph, start_node):
visited, need_visit = list(), list()
need_visit.append(start_node)
while need_visit:
node = need_visit.pop()
if node not in visited:
visited.append(node)
need_visit.extend(graph[node])
return visited
탐욕 알고리즘(Greddy Algorithm)
탐욕 알고리즘 예
def min_coin_count(value, coin_list):
coin_list.sort(reverse=True)
total_coin_count = 0
details = list()
for coin in coin_list:
coin_num = value // coin
total_coin_count += coin_num
value -= coin_num * coin
details.append([coin, coin_num])
return total_coin_count, details
array(배열)
array의 data 타입
np.array([1,2,3.14,True], dtype=int)
#array([1, 2, 3, 1])
np.array([1,2,3.14,True,'1234'], dtype=int)
#array([ 1, 2, 3, 1, 1234])
인덱싱과 슬라이싱
arr2d = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
arr2d.shape # (3, 4) - 3열 4행
0행 가져오기
#[1 2 3 4]
print(arr2d[0])
print(arr2d[0])
print(arr2d[0,:])
0열 가져오기
#[1 5 9]
print(arr2d[:,0])
Fancy 인덱싱
np.array([[1,2,3,4], 5,6,7,8], [9,10,11,12]])
#array([[1, 2, 3, 4], [5, 6, 7, 8]])
arr2d[[0,1]]
arr2d[[0,1],:]
Boolean 인덱싱
arr1 = np.array(['🤯','🥹','🍗','🥲','😇'])
selValue = [True, True, False, False, True]
arr1[selValue] # array(['🤯', '🥹', '😇'], dtype='<U1')
arr2d = np.array([[1,2,3,4], 5,6,7,8], [9,10,11,12]])
arr2d > 7
# array([[False, False, False, False],
# [False, False, False, True],
# [ True, True, True, True]])
연산자
덧셈 연산
a = np.array([[1,2,3], [2,3,4]])
b = np.array([[3,4,5], [1,2,3]])
a + b # array([[4, 6, 8], [3, 5, 7]])
뺄셈 연산
a - b
# array([[-2, -2, -2], [ 1, 1, 1]])
곱셉 연산
a * b
# array([[ 3, 8, 15], [ 2, 6, 12]])
나눗셈 연산
a / b
# array([[0.33333333, 0.5 , 0.6 ],
# [2. , 1.5 , 1.33333333]])
내적(dot product) = dot
np.dot(a,b)
#array([[22, 28], [22, 28], [31, 40]])
arange
np.arange(1, 11)
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
sort
np.sort(arr1)[::-1] # 내림차순
행 정렬
np.sort(arr2d, axis = 0) # axis=0: 행
열 정렬
np.sort(arr2d, axis = 1) # axsis=1: 열
축의 마지막 방향
np.sort(arr2d, axis = -1) # axis=-1: 축이 많을 경우 마지막 축의 값을 설정
숫자의 단일 연산
a = np.array([[1,2,3], [4,5,6]])
a + 3 # array([[4, 5, 6], [7, 8, 9]])
a - 3 # array([[-2, -1, 0], [ 1, 2, 3]])
a / 3 # array([[ 3, 6, 9], [12, 15, 18]])
a * 3 # array([[0.33333333, 0.66666667, 1. ], [1.33333333, 1.66666667, 2. ]])