def binary_search(arr, target): #정렬, 찾고자 하는 값이 인수로 들어감
left = 0 #arr의 맨왼쪽인덱스
right = len(arr) - 1 #arr의 맨오른쪽인덱스
while left <= right: #비교했을 때 오른쪽이 작을때까지 반복 (즉 탐색할 배열이 없을때까지)
mid = (left + right) // 2
if arr[mid] == target: #가운데데 인덱스의 값이 찾고자하는 값이면
return mid #가운데인덱스를 리턴
elif arr[mid] < target: #찾고자하는 값보다 가운데 인덱스의 값이 작으면
left = mid + 1 #맨왼쪽, 첫번째 인덱스가 중간값부터 시작됨 (시작점을 바꿔서 기존 정렬을 반으로나누는것 뜻)
else:
right = mid - 1 #맨오른쪽, 마지막 인덱스가 중간값부터 시작됨(시작점을 바꿔서 기존 정렬을 반으로나누는것 뜻
return -1 #값을 못찾으면 -1 내보냄 너가 찾는 값없어~~
이진 탐색은 검색, 정렬, 최솟값/최댓값 찾기 등 다양한 문제에서 사용됩니다. 이진 탐색은 탐색할 배열이 정렬되어 있어야 한다는 조건이 있지만, 이 조건을 만족한다면 빠른 탐색을 수행할 수 있는 알고리즘입니다. 이진 탐색은 효율적인 탐색을 위해 항상 고려해야 할 알고리즘 중 하나입니다.
def dfs(graph, start, visited): #인자에 그래프, 시작노드, 방문한 노드 집합
visited.add(start) # 현재 노드를 방문 처리
print(start, end=' ')
# 현재 노드와 인접한 노드들을 순회
for adjacent_node in graph[start]:
if adjacent_node not in visited: #만약에 방문하지 않은 노드라면
dfs(graph, adjacent_node, visited) #그 노드를 시작노드로 해서 재귀함수 실행 -> 현재노드를 방문처리~ 반복
# 그래프를 인접 리스트로 표현한 예시
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
visited = set() # 방문한 노드를 저장하기 위한 집합
print("깊이 우선 탐색 결과:")
dfs(graph, 'A', visited)
그래프의 모든 노드를 깊이를 우선하여 탐색하는 DFS는
재귀함수 또는 스택으로 구현될 수 있다.
여기서는 재귀함수로 구현됨
코드풀이~
시작노드를 방문처리하고
그 시작노드의 인접노드가 방문하지 않은 노드라면
해당 노드를 다시 시작노드로 설정해서 재귀함수~ (다시 그 시작노드로 방문처리하고 반복)
스택으로 구현한 코드
def dfs(graph, start):
visited = set() # 방문한 노드를 저장하기 위한 집합
stack = [start] # 탐색할 노드를 저장하기 위한 스택
while stack:
node = stack.pop() # 스택의 가장 위에 있는 노드를 가져옴
if node not in visited:
visited.add(node)
print(node, end=' ')
# 인접한 노드들 중에서 방문하지 않은 노드를 스택에 추가
for adjacent_node in graph[node]:
if adjacent_node not in visited:
stack.append(adjacent_node)
# 그래프를 인접 리스트로 표현한 예시
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("깊이 우선 탐색 결과:")
dfs(graph, 'A')
BFS 너비탐색 알고리즘 코드구현
from collections import deque
#먼저 collections 모듈에서 deque를 가져옵니다.
#deque는 양쪽 끝에서의 빠른 append와 popleft 연산을 지원하는 큐(queue) 자료구조입니다
#이 함수는 그래프와 시작노드를 인자로 받는다.
def bfs(graph, start):
visited = set() # 방문한 노드를 저장하기 위한 집합 초기셋팅
queue = deque([start]) # 탐색할 노드를 저장하기 위한 큐
visited.add(start) # 시작 노드를 방문 처리
#큐가 비어있지 않은 동안 반복한다
while queue:
node = queue.popleft() # 큐에서 가장 앞에 있는 노드를 가져옴. popleft를 해서큐에서 노드를 제거
print(node, end=' ')
# 인접한 노드들 중에서 방문하지 않은 노드를 큐에 추가하고 방문 처리
for adjacent_node in graph[node]: #현재 처리중인 node의 인접한 노드들을 순회
if adjacent_node not in visited:#방문했다는 집합에 해당노드가 없다면
queue.append(adjacent_node) #큐에다가 인접 노드 넣기
visited.add(adjacent_node) #방문했다고 방문집합에 추가하기
# 그래프를 인접 리스트로 표현한 예시
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
print("너비 우선 탐색 결과:")
bfs(graph, 'A')