-
자료구조: 그래프(Graph)Algorithm & Data Structure/DataStructure 2024. 11. 17. 21:24반응형
1. 그래프란 무엇인가?
그래프는 정점(Vertex)과 간선(Edge)으로 구성된 데이터 구조입니다. 각 정점은 데이터를 나타내며, 간선은 정점 간의 관계 또는 연결을 나타냅니다. 그래프는 네트워크 구조를 표현하는 데 매우 적합합니다. 예를 들어, 소셜 네트워크, 도로 지도, 인터넷의 링크 구조 등이 있습니다.
그래프의 구성 요소
- 정점(Vertex):
- 데이터를 저장하는 노드입니다.
- 예: 도시, 사람, 웹 페이지 등.
- 간선(Edge):
- 정점 간의 관계를 나타냅니다.
- 방향이 있는 경우 유방향(Directed), 없는 경우 무방향(Undirected)입니다.
- 가중치(Weight):
- 간선에 추가 정보(예: 거리, 비용)를 저장하는 값입니다.
2. 그래프의 종류
- 무방향 그래프(Undirected Graph):
- 간선에 방향이 없습니다.
- 예: Facebook 친구 관계.
- A와 B가 친구라면, A → B, B → A 모두 가능합니다.
- 유방향 그래프(Directed Graph):
- 간선에 방향이 있습니다.
- 예: Twitter 팔로우 관계.
- A가 B를 팔로우한다고 해서, B가 A를 팔로우하는 것은 아닙니다.
- 가중치 그래프(Weighted Graph):
- 간선에 가중치가 포함된 그래프입니다.
- 예: Google 지도에서 도시 간의 거리.
- 비가중치 그래프(Unweighted Graph):
- 간선에 가중치가 없는 그래프입니다.
- 사이클 그래프(Cyclic Graph):
- 경로가 원형으로 돌아올 수 있는 그래프입니다.
- 예: 전력망의 순환 구조.
- 비사이클 그래프(Acyclic Graph):
- 경로가 원형으로 돌아오지 않는 그래프입니다.
- 예: 프로젝트 작업 흐름을 나타내는 DAG(Directed Acyclic Graph).
3. 그래프 표현 방식
그래프는 데이터를 저장하는 방식에 따라 다음 두 가지로 표현할 수 있습니다.
3.1. 인접 리스트(Adjacency List)
- 정점별로 연결된 정점 목록을 저장합니다.
- 메모리 효율적이며 대부분의 경우 적합합니다.
- 시간 복잡도:
- 특정 간선 존재 확인: O(V)
- 정점에 연결된 모든 간선 확인: O(E)
- 장점:
- 공간 효율적, 간선이 적은 그래프에 적합.
- 단점:
- 특정 정점 간의 연결 여부를 확인하기 어려움.
Golang 예제:
graph := map[string][]string{ "A": {"B", "C"}, "B": {"A", "D"}, "C": {"A", "D"}, "D": {"B", "C"}, }
Java 예제:
Map<String, List<String>> graph = new HashMap<>(); graph.put("A", Arrays.asList("B", "C")); graph.put("B", Arrays.asList("A", "D")); graph.put("C", Arrays.asList("A", "D")); graph.put("D", Arrays.asList("B", "C"));
3.2. 인접 행렬(Adjacency Matrix)
- NxN 2차원 배열로 연결 여부와 가중치를 저장합니다.
- 시간 복잡도:
- 특정 간선 존재 확인: O(1)
- 정점에 연결된 모든 간선 확인: O(V)
- 장점:
- 특정 간선 확인 속도가 빠름.
- 밀집 그래프(Dense Graph)에 적합.
- 단점:
- 공간 비효율적, 희소 그래프(Sparse Graph)에 부적합.
Golang 예제:
graph := [][]int{ {0, 1, 1, 0}, {1, 0, 0, 1}, {1, 0, 0, 1}, {0, 1, 1, 0}, }
Java 예제:
int[][] graph = { {0, 1, 1, 0}, {1, 0, 0, 1}, {1, 0, 0, 1}, {0, 1, 1, 0}, };
4. 그래프 탐색
그래프 탐색은 정점과 간선을 따라 이동하며 데이터를 검색하거나 작업을 수행하는 과정입니다. 주요 탐색 방법은 다음과 같습니다.
4.1. 깊이 우선 탐색(DFS)
- 특정 정점에서 출발하여 한 경로를 끝까지 탐색한 후, 다른 경로를 탐색.
- 스택(Stack)이나 재귀(Recursion)를 사용.
시간 복잡도: O(V + E)
Golang DFS 예제:
func dfs(graph map[string][]string, start string, visited map[string]bool) { visited[start] = true fmt.Println(start) for _, neighbor := range graph[start] { if !visited[neighbor] { dfs(graph, neighbor, visited) } } }
Java DFS 예제:
public static void dfs(Map<String, List<String>> graph, String start, Set<String> visited) { visited.add(start); System.out.println(start); for (String neighbor : graph.get(start)) { if (!visited.contains(neighbor)) { dfs(graph, neighbor, visited); } } }
4.2. 너비 우선 탐색(BFS)
- 특정 정점에서 가까운 정점부터 탐색.
- 큐(Queue)를 사용.
시간 복잡도: O(V + E)
Golang BFS 예제:
func bfs(graph map[string][]string, start string) { queue := []string{start} visited := make(map[string]bool) for len(queue) > 0 { current := queue[0] queue = queue[1:] if visited[current] { continue } visited[current] = true fmt.Println(current) queue = append(queue, graph[current]...) } }
Java BFS 예제:
public static void bfs(Map<String, List<String>> graph, String start) { Queue<String> queue = new LinkedList<>(); Set<String> visited = new HashSet<>(); queue.add(start); while (!queue.isEmpty()) { String current = queue.poll(); if (visited.contains(current)) { continue; } visited.add(current); System.out.println(current); queue.addAll(graph.get(current)); } }
5. 그래프의 주요 알고리즘
- 최단 경로 탐색:
- Dijkstra, Bellman-Ford, Floyd-Warshall 알고리즘.
- 예: Google 지도에서 가장 빠른 경로 찾기.
- 최소 신장 트리(MST):
- Kruskal, Prim 알고리즘.
- 예: 통신 네트워크 구축 비용 최적화.
- 강한 연결 요소(SCC):
- Kosaraju, Tarjan 알고리즘.
- 예: 소셜 네트워크 내 그룹 찾기.
- 위상 정렬(Topological Sort):
- DAG에서 작업의 순서를 정렬.
- 예: 프로젝트 일정 관리.
6. 그래프의 응용 사례
- 네트워크 라우팅:
- 최단 경로 탐색을 활용하여 데이터 전송 최적화.
- 웹 크롤러:
- 인터넷의 링크 구조를 분석하여 검색 엔진에 활용.
- 소셜 네트워크 분석:
- 친구 추천 알고리즘, 커뮤니티 탐지.
- AI 및 머신러닝:
- 그래프 뉴럴 네트워크(GNN)를 활용한 데이터 학습.
- 추천 시스템:
- 그래프에서 연결 강도를 분석하여 사용자 맞춤 추천.
반응형'Algorithm & Data Structure > DataStructure' 카테고리의 다른 글
자료구조: 해시테이블(Hash Table) (2) 2024.11.24 자료구조: 해시맵(Hash Map) (3) 2024.11.23 자료구조: 큐(Queue) (0) 2024.11.02 자료구조: 스택(Stack) (0) 2024.11.02 golang: Array vs LinkedList (0) 2024.07.31 - 정점(Vertex):