8. 图(Graph)
8. 图(Graph)
问题:需要表达多对多的关系,如社交网络、地图导航、依赖关系。
核心:由顶点(Vertex)和边(Edge)组成。可以用邻接表(每个顶点存邻居列表)或邻接矩阵(二维数组)表示。
特点
- 顶点 + 边,有向/无向,有权/无权
- 邻接表:空间 O(V+E),适合稀疏图
- 邻接矩阵:空间 O(V²),适合密集图,O(1) 判断两点是否相连
优点
- 能表达复杂的多对多关系
- 灵活:有向/无向、加权/无权、有环/无环
- BFS/DFS 遍历算法成熟
缺点
- 实现复杂,尤其涉及权重和最短路径
- 稀疏图用邻接矩阵浪费空间
- 可能有环,遍历时需标记已访问
- 最短路径等算法时间复杂度较高
// 邻接表实现
class Graph {
#adj = new Map();
addVertex(v) {
if (!this.#adj.has(v)) this.#adj.set(v, []);
}
addEdge(v, w) {
this.addVertex(v);
this.addVertex(w);
this.#adj.get(v).push(w);
this.#adj.get(w).push(v); // 无向图
}
// BFS 广度优先搜索
bfs(start) {
const visited = new Set([start]);
const queue = [start];
const order = [];
while (queue.length) {
const v = queue.shift();
order.push(v);
for (const neighbor of this.#adj.get(v) ?? []) {
if (!visited.has(neighbor)) {
visited.add(neighbor);
queue.push(neighbor);
}
}
}
return order;
}
// DFS 深度优先搜索
dfs(start, visited = new Set(), order = []) {
visited.add(start);
order.push(start);
for (const neighbor of this.#adj.get(start) ?? []) {
if (!visited.has(neighbor)) {
this.dfs(neighbor, visited, order);
}
}
return order;
}
}
const g = new Graph();
g.addEdge('A', 'B');
g.addEdge('A', 'C');
g.addEdge('B', 'D');
g.addEdge('C', 'D');
console.log(g.bfs('A')); // ['A', 'B', 'C', 'D']
console.log(g.dfs('A')); // ['A', 'B', 'D', 'C']package graph
// 邻接表实现
type Graph struct {
adj map[string][]string
}
func NewGraph() *Graph {
return &Graph{adj: make(map[string][]string)}
}
func (g *Graph) AddEdge(v, w string) {
g.adj[v] = append(g.adj[v], w)
g.adj[w] = append(g.adj[w], v) // 无向图
}
// BFS
func (g *Graph) BFS(start string) []string {
visited := map[string]bool{start: true}
queue := []string{start}
var order []string
for len(queue) > 0 {
v := queue[0]
queue = queue[1:]
order = append(order, v)
for _, neighbor := range g.adj[v] {
if !visited[neighbor] {
visited[neighbor] = true
queue = append(queue, neighbor)
}
}
}
return order
}
// DFS
func (g *Graph) DFS(start string) []string {
visited := map[string]bool{}
var order []string
var dfs func(v string)
dfs = func(v string) {
visited[v] = true
order = append(order, v)
for _, neighbor := range g.adj[v] {
if !visited[neighbor] {
dfs(neighbor)
}
}
}
dfs(start)
return order
}社交网络(好友关系)、地图导航(最短路径 Dijkstra)、Git 提交图、网页爬虫(URL 图)都是图的应用。