前言
图是一种用于表示对象及其相互关系的数据结构。图由顶点(也称为节点)和边组成,边连接顶点,表示顶点之间的关系。根据边的方向性,图可以分为有向图和无向图。根据边的权重,图可以分为加权图和非加权图。
实现原理
邻接表(Adjacency List):
- 用一个数组或链表表示每个顶点的邻接顶点。
- 每个顶点都有一个链表(或列表),存储其所有邻接顶点。
- 优点:适合表示稀疏图,空间复杂度低,为 O(V+E)O(V + E)O(V+E),其中 VVV 是顶点数,EEE 是边数。
- 缺点:查找两个顶点之间是否存在边的时间复杂度为 O(V)O(V)O(V)(链表实现)或 O(logV)O(\log V)O(logV)(平衡树或哈希表实现)。
有一个简单的无向图
html
A - B - C
| |
D - E - F
动画过程
Depth-First Search Visualization
具体代码实现
java
import java.util.*;
class Graph {
private Map<String, List<String>> adjList;
public Graph() {
adjList = new HashMap<>();
}
// 添加边的方法
public void addEdge(String v, String w) {
adjList.putIfAbsent(v, new ArrayList<>());
adjList.putIfAbsent(w, new ArrayList<>());
adjList.get(v).add(w);
adjList.get(w).add(v); // 无向图,双向添加
}
// 打印图的方法(可选,用于调试)
public void printGraph() {
for (String v : adjList.keySet()) {
System.out.print(v + ": ");
for (String w : adjList.get(v)) {
System.out.print(w + " ");
}
System.out.println();
}
}
// 递归实现深度优先搜索
public void DFSRecursive(String start) {
Set<String> visited = new HashSet<>();
DFSUtil(start, visited);
}
private void DFSUtil(String v, Set<String> visited) {
visited.add(v);
System.out.print(v + " ");
for (String neighbor : adjList.get(v)) {
if (!visited.contains(neighbor)) {
DFSUtil(neighbor, visited);
}
}
}
// 迭代实现深度优先搜索
public void DFSIterative(String start) {
Set<String> visited = new HashSet<>();
Stack<String> stack = new Stack<>();
stack.push(start);
while (!stack.isEmpty()) {
String v = stack.pop();
if (!visited.contains(v)) {
visited.add(v);
System.out.print(v + " ");
// 为了与递归实现顺序一致,反转邻接节点的顺序
List<String> neighbors = adjList.get(v);
Collections.reverse(neighbors);
for (String neighbor : neighbors) {
if (!visited.contains(neighbor)) {
stack.push(neighbor);
}
}
}
}
}
public static void main(String[] args) {
Graph g = new Graph();
g.addEdge("A", "B");
g.addEdge("A", "D");
g.addEdge("B", "C");
g.addEdge("B", "E");
g.addEdge("D", "E");
g.addEdge("E", "F");
System.out.println("Graph representation:");
g.printGraph();
System.out.println("Depth First Traversal (Recursive) starting from node A:");
g.DFSRecursive("A");
System.out.println();
System.out.println("Depth First Traversal (Iterative) starting from node A:");
g.DFSIterative("A");
}
}
QA:待定