그래프 표현 방법: 인접 행렬(Adjacency Matrix)과 인접 리스트(Adjacency List) 비교
그래프는 컴퓨터 과학에서 매우 중요한 자료구조로, 데이터 간의 관계를 효과적으로 표현할 수 있다.
그래프를 표현하는 방법을 선택할 때는 해결하려는 문제의 특성과 그래프의 구조를 고려해야 한다.
- 간선이 적은 희소 그래프의 경우 인접 리스트가 메모리와 성능 면에서 우수
- 간선이 많은 밀집 그래프나 정점 간 연결 여부를 빠르게 확인해야 하는 경우에는 인접 행렬이 적합하다.
실제로는 두 방법을 혼합하거나 응용한 자료구조를 사용하기도 한다.
많은 실제 응용 사례(소셜 네트워크, 웹 페이지 연결 등)에서는 정점 수에 비해 간선 수가 적은 희소 그래프의 특성을 가지므로 인접 리스트가 더 많이 사용되는 경향이 있다.
인접 행렬(Adjacency Matrix)
인접 행렬은 2차원 배열을 사용하여 그래프의 연결 관계를 표현하는 방법.
기본 개념
- n개의 정점이 있다면 n×n 크기의 2차원 배열을 생성한다.
- 행렬의 각 원소 M[i][j]는 정점 i에서 정점 j로 가는 간선이 있으면 1(또는 가중치), 없으면 0을 저장한다.
- 무방향 그래프의 경우 인접 행렬은 대칭 행렬이 된다.
인접 행렬의 예시
무방향 그래프 (Undirected Graph)
인접 행렬 표현
A | B | C | D | |
---|---|---|---|---|
A | 0 | 1 | 1 | 0 |
B | 1 | 0 | 0 | 1 |
C | 1 | 0 | 0 | 1 |
D | 0 | 1 | 1 | 0 |
방향 그래프 (Directed Graph)
인접 행렬 표현
A | B | C | D | |
---|---|---|---|---|
A | 0 | 1 | 1 | 0 |
B | 0 | 0 | 0 | 0 |
C | 0 | 0 | 0 | 1 |
D | 0 | 0 | 0 | 0 |
구현 예시 (Python)
|
|
인접 행렬이 유리한 경우
- 그래프의 간선 밀도가 높은 경우 (밀집 그래프)
- 두 정점 간 간선 존재 여부를 자주 확인해야 하는 경우
- 가중치 정보를 쉽게 표현하고 접근해야 하는 경우
- 알고리즘이 행렬 연산을 기반으로 하는 경우 (예: 플로이드-워셜 알고리즘)
인접 행렬 활용 분야
- 플로이드-워셜 알고리즘 (모든 정점 간 최단 경로)
- 네트워크 연결 상태 분석
- 이미지 및 그래픽 처리 (픽셀 연결성 분석)
- 완전 그래프(Complete Graph)처럼 간선이 많은 경우
인접 리스트(Adjacency List)
인접 리스트는 각 정점마다 해당 정점과 인접한 정점들의 리스트를 저장하는 방법이다.
기본 개념
- 모든 정점에 대해 해당 정점과 연결된 다른 정점들의 리스트를 유지한다.
- 정점 수만큼의 리스트 배열이 필요하다.
- 가중치 그래프의 경우, 연결된 정점과 함께 가중치도 저장한다.
인접 리스트의 예시
무방향 그래프 (Undirected Graph)
인접 리스트 표현
방향 그래프 (Directed Graph)
인접 리스트 표현
구현 예시 (Python)
|
|
인접 리스트가 유리한 경우
- 그래프의 간선 밀도가 낮은 경우 (희소 그래프)
- 메모리 사용량이 중요한 경우
- 모든 간선을 순회해야 하는 경우
- 특정 정점에서 출발하는 모든 간선을 자주 찾아야 하는 경우
- 그래프 탐색 알고리즘(BFS, DFS)을 구현할 때
인접 리스트 활용 분야
- 다익스트라 알고리즘 (최단 경로 탐색)
- 소셜 네트워크 분석 (Facebook, Twitter)
- 추천 시스템 (Netflix, YouTube)
- 네트워크 라우팅 (인터넷 패킷 경로 탐색)
- 웹 크롤링 (페이지 간 링크 분석)
인접 행렬과 인접 리스트 비교
특성 | 인접 행렬 (Adjacency Matrix) | 인접 리스트 (Adjacency List) |
---|---|---|
메모리 사용량 | O(V²) - 정점 수의 제곱에 비례 | O(V + E) - 정점 수와 간선 수의 합에 비례 |
간선 존재 확인 | O(1) - 상수 시간 | O(degree(V)) - 정점의 차수에 비례 |
모든 간선 순회 | O(V²) - 행렬 전체 순회 필요 | O(V + E) - 모든 정점과 간선 순회 |
특정 정점의 모든 인접 정점 찾기 | O(V) - 해당 행 전체 확인 필요 | O(degree(V)) - 해당 정점의 리스트만 확인 |
간선 추가 | O(1) - 배열 원소 변경 | O(1) - 리스트에 추가 |
간선 제거 | O(1) - 배열 원소 변경 | O(degree(V)) - 리스트에서 검색 후 제거 |
그래프 밀집도에 따른 효율성 | 밀집 그래프에 효율적 | 희소 그래프에 효율적 |
구현 복잡도 | 간단함 | 약간 복잡함 |
공간 효율성 | 희소 그래프에서 비효율적 | 메모리 사용이 최적화됨 |
특정 두 정점 간 연결 확인 | O(1) - 즉시 확인 가능 | O(degree(V)) - 리스트 검색 필요 |
그래프 순회 알고리즘 구현 | 복잡하고 느림 | 간단하고 빠름 |
적합한 그래프 유형 | 작은 그래프, 완전 그래프 | 큰 그래프, 희소 그래프 |
웹 그래프와 같은 대규모 그래프 | 비실용적 | 실용적 |
동적 그래프(변화가 많은) | 비효율적 | 효율적 |