나동빈님의 서적 '이것이 취업을 위한 코딩테스트다'를 읽고 정리하였습니다.
꼭 필요한 자료구조 기초
탐색(Search)
- 많은 양의 데이터 중에서 원하는 데이터를 찾는 과정
- 프로그래밍에서는 그래프, 트리 등의 자료구조 안에서 탐색을 하는 문제를 자주 다룸
- DFS와 BFS는 대표적인 탐색 알고리즘
- 두 알고리즘의 원리를 제대로 이해하려면 기본 자료구조인 스택(Stack)과 큐(Queue), 그리고 재귀 함수(Recursion Function)에 대한 이해가 필요
자료구조(Data Structure)
- 데이터를 표현하고 관리하고 처리하기 위한 구조
- 그중 스택과 큐는 자료구조의 기초 개념으로 다음의 두 핵심적인 함수로 구성됨
- 삽입(Push): 데이터를 삽입
- 삭제(Pop): 데이터를 삭제
- 실제로 스택과 큐를 사용할 때, 삽입과 삭제 외에도 오버플로와 언더플로를 고려해야 함
- 오버플로(Overflow): 특정한 자료구조가 수용할 수 있는 데이터의 크기만큼 이미 가득 찬 상태에서 삽입 연산을 수행할 때 발생
- 언더플로(Underflow): 특정한 자료구조에 데이터가 전혀 들어 있지 않은 상태에서 삭제 연산을 수행할 때 발생
- 그중 스택과 큐는 자료구조의 기초 개념으로 다음의 두 핵심적인 함수로 구성됨
스택(Stack)
스택은 후입선출(LIFO: Last in First Out) 구조이다.
큐(Queue)
큐는 선입선출(FIFO: First In First Out) 구조이다.
재귀 함수(Recursion Function)
- 자기 자신을 다시 호출하는 함수
- 재귀 함수가 언제 끝날지, 종료 조건을 꼭 명시해야 한다. 자칫 종료 조건을 명시하지 않으면 함수가 무한 호출될 수 있다.
스택과 재귀 함수의 연관성
- 컴퓨터 내부에서 재귀 함수의 수행은 스택 자료구조를 이용
- 함수를 계속 호출했을 때 가작 마지막에 호출한 함수가 먼저 수행을 끝내야 그 앞의 함수 호출이 종료됨
- 컴퓨터 구조 측면에서, 연속해서 호출되는 함수는 메인 메모리의 스택 공간에 적재
- 스택 자료구조를 활용해야 하는 상당수 알고리즘은 재귀 함수를 이용해서 간편하게 구현될 수 있음
- DFS가 대표적인 예
재귀 함수의 장점(vs. 반복문)
- 코드가 더 간결하다
- 재귀 함수가 수학의 점화식 (재귀식)을 그대로 코드로 구현했기 때문
- 수학에서 점화식은 특정한 함수를 자신보다 더 작은 변수에 대한 함수와의 관계료 표현한 것
그래프(Graph)
- 노드(Node)와 간선(Edge)로 표현
- 노드는 정점(Vertex)으로도 불림
- 그래프 탐색
- 하나의 노드를 시작으로 다수의 노드를 방문하는 것
- 두 노드가 간선으로 연결되어 있을 때 두 노드는 인접하다(Adjacent)라고 함
- 그래프의 표현
- 인접 행렬(Adjacency Matrix)
- 2차원 배열로 그래프의 연결 관계를 표현하는 방식
- 연결되지 않은 노드끼리는 무한(Infinity)의 비용이라고 작성
- 인접 리스트(Adjacency List)
- 연결 리스트로 그래프의 연결 관계를 표현하는 방식
- 차이
- 메모리 측면
- 인접 행렬 방식은 모든 관계를 저장하므로 노드 개수가 많을수록 메모리가 불필요하게 낭비
- 인접 리스트 방식은 연결된 정보만을 저장하기 때문에 메모리를 효율적으로 사용
- 속도 측면
- 인접 리스트 방식은 인접 행렬 방식에 비해 특정한 두 노드가 연결되어 있는지에 대한 정보를 얻는 속도가 느림
- 인접 리스트 방식은 연결된 데이터를 하나씩 확인해야 함
- 메모리 측면
- 인접 행렬(Adjacency Matrix)
DFS(Depth-First Search)
DFS는 깊이 우선 탐색이라고도 부르며, 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘이다.
DFS의 동작 과정
- 탐색 시작 노드를 스택에 삽입하고 방문 처리를 한다.
- 스택의 최상단 노드에 방문하지 않은 인접 노드가 있으면 그 인접 노드를 스택에 넣고 방문 처리를 한다. 방문하지 않은 인접 노드가 없으면 스택에서 최상단 노드를 꺼낸다.
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.
** 방문 처리는 스택에 한 번 삽입되어 처리된 노드가 다시 삽입되지 않게 체크하는 것 **
BFS(Depth-First Search)
BFS는 너비 우선 탐색이라고도 부르며, 그래프에서 가까운 노드부터 우선적으로 탐색하는 알고리즘이다. BFS는 주로 선입선출 방식인 큐 자료구조를 이용해 구현한다.
BFS의 동작 과정
- 탐색 시작 노드를 큐에 삽입하고 방문 처리를 한다.
- 큐에서 노드를 꺼내 해당 노드의 인접 노드 중에서 방문하지 않은 노드를 모두 큐에 삽입하고 방문 처리를 한다.
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.
DFS와 BFS의 구현 방식
가장 간결한 방식은 아래와 같다.
(사진 출처: 서적)
- BFS는 주로 경로 문제, 특히 최단거리를 구해야하는 문제 유형에 주로 활용
- DFS는 경로의 특징을 저장해둬야 하는 문제에 활용
- DFS는 재귀함수를 이용해서, BFS는 큐를 이용해서 구현하는 것이 일반적
- DFS는 스택으로도 구현
- DFS는 스택에서 노드 정보를 pop할때 방문 처리
- BFS는 큐에 노드 정보를 push할 때 방문 처리
'Computer Science > 📝Algorithm' 카테고리의 다른 글
[Algorithm] 이진 탐색 (Binary Search) (0) | 2021.10.10 |
---|---|
[Algorithm] 정렬 (Sorting) (0) | 2021.10.10 |
[Algorithm] 구현 (Implementation) (0) | 2021.10.02 |
[Algorithm] 그리디 (Greedy) (0) | 2021.10.02 |
[Algorithm] 복잡도 (Complexity) (0) | 2021.10.02 |