Undirected Graph vs. Directed Graph(无向图 vs. 有向图)

157 阅读2分钟

在构建图数据结构时,无向图(Undirected Graph)有向图(Directed Graph) 的处理方式不同,影响着 存储方式、访问逻辑和应用场景。以下是基于代码的分析:

🔹 1. 无向图(Undirected Graph)

🔹 代码解析

java
复制编辑
Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();

private void buildGraph(int [][] edges, Map<Integer, Map<Integer, Integer>> graph){
    for(int [] edge: edges){
        int u = edge[0];
        int v = edge[1];
        int weight = edge[2];

        // 初始化节点
        graph.putIfAbsent(u, new HashMap<>());
        graph.putIfAbsent(v, new HashMap<>());

        // 无向图:双向存储边
        graph.get(u).put(v, weight);
        graph.get(v).put(u, weight);
    }
}

🔹 关键点

  1. 双向存储边

    java
    复制编辑
    graph.get(u).put(v, weight);
    graph.get(v).put(u, weight);
    
    • u → vv → u 都存储,确保无向图的双向性。
  2. 适用场景

    • 最短路径搜索(Dijkstra, Floyd-Warshall)
    • 连通性问题(DFS, BFS)
    • 最小生成树(Kruskal, Prim)
  3. 时间复杂度

    • 构建图的时间复杂度 O(E) ,其中 E 是边数。
    • 访问 graph.get(u).put(v, weight)O(1)

🔸 2. 有向图(Directed Graph)

🔸 代码解析

java
复制编辑
Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();
Map<Integer, Integer> IndegreeMap = new HashMap<>();

private void buildGraph(int [][] edges, Map<Integer, Map<Integer, Integer>> graph, Map<Integer, Integer> IndegreeMap){
    for(int [] edge: edges){
        int u = edge[0];
        int v = edge[1];
        int weight = edge[2];

        // 初始化节点
        graph.putIfAbsent(u, new HashMap<>());

        // 有向图:仅存 u → v
        graph.get(u).put(v, weight);

        // 记录 v 的入度
        IndegreeMap.put(v, IndegreeMap.getOrDefault(v, 0) + 1);
    }
}

🔸 关键点

  1. 单向存储边

    java
    复制编辑
    graph.get(u).put(v, weight);
    
    • 只存储 u → v,不存储 v → u,确保方向性。
  2. 引入入度(IndegreeMap)

    java
    复制编辑
    IndegreeMap.put(v, IndegreeMap.getOrDefault(v, 0) + 1);
    
    • 用于 拓扑排序(Topological Sorting) ,例如:

      • 课程安排(Course Schedule)
      • 任务调度(Task Scheduling)
      • DAG 最短路径(Shortest Path in DAG)
  3. 适用场景

    • 任务调度(拓扑排序)
    • 单向最短路径(Dijkstra, Bellman-Ford)
    • 有向无环图(DAG)问题
  4. 时间复杂度

    • 构建图的时间复杂度 O(E)
    • 访问 graph.get(u).put(v, weight)O(1)

🆚 Undirected vs. Directed Graph 总结

对比项无向图 (Undirected Graph)有向图 (Directed Graph)
边的存储双向存储u → vv → u单向存储u → v
数据结构Map<Integer, Map<Integer, Integer>>Map<Integer, Map<Integer, Integer>> + IndegreeMap
入度计算❌ 不需要✅ 需要(用于拓扑排序)
适用场景最短路径、连通性、最小生成树拓扑排序、DAG 处理、单向路径
时间复杂度O(E)O(E)

🚀 结论

  • 无向图 适用于 最短路径、连通性检查、最小生成树 等问题,需要双向存储边。
  • 有向图 适用于 拓扑排序、DAG 处理、单向最短路径 等问题,并且需要记录 入度 以支持相关算法。