🕸️ 圖論學習指南

← 返回學習中心

什麼是圖?

圖(Graph)是一種由頂點(Vertex)邊(Edge)組成的非線性資料結構,用於表示物件之間的關係。

無向圖範例:

    A —— B
   /   |   \
  C     D —— E

圖的類型

圖的表示方法

1. 鄰接矩陣(Adjacency Matrix)

    A B C D E
A[ 0, 1, 1, 0, 0 ]
B[ 1, 0, 0, 1, 0 ]
C[ 1, 0, 0, 0, 0 ]
D[ 0, 1, 0, 0, 1 ]
E[ 0, 0, 0, 1, 0 ]

2. 鄰接串列(Adjacency List)

A → B → C
B → A → D
C → A
D → B → E
E → D

圖的演算法

BFS 廣度優先搜尋

時間: O(V + E)
從起點開始,逐層向外擴展搜尋

DFS 深度優先搜尋

時間: O(V + E)
沿著路徑深入,直到無法繼續為止

Dijkstra 最短路徑

時間: O((V+E)logV)
單源最短路徑(需為非負權重)

Bellman-Ford

時間: O(VE)
可處理負權重的最短路徑

Floyd-Warshall

時間: O(V³)
所有點對最短路徑

Kruskal / Prim

時間: O(ElogV)
最小生成樹(MST)

程式碼範例 - BFS 與 DFS

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

class Graph {
private:
    int V;
    vector<vector<int>> adj;
    
public:
    Graph(int v) : V(v), adj(v) {}
    
    void addEdge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);  // 無向圖
    }
    
    // BFS 廣度優先搜尋
    void BFS(int start) {
        vector<bool> visited(V, false);
        queue<int> q;
        
        visited[start] = true;
        q.push(start);
        
        while (!q.empty()) {
            int curr = q.front();
            q.pop();
            cout << curr << " ";
            
            for (int neighbor : adj[curr]) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    q.push(neighbor);
                }
            }
        }
        cout << endl;
    }
    
    // DFS 深度優先搜尋
    void DFS(int start) {
        vector<bool> visited(V, false);
        DFSUtil(start, visited);
        cout << endl;
    }
    
private:
    void DFSUtil(int curr, vector<bool>& visited) {
        visited[curr] = true;
        cout << curr << " ";
        
        for (int neighbor : adj[curr]) {
            if (!visited[neighbor]) {
                DFSUtil(neighbor, visited);
            }
        }
    }
};

int main() {
    Graph g(5);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(1, 3);
    g.addEdge(2, 3);
    g.addEdge(3, 4);
    
    cout << "BFS (從 0 開始): ";
    g.BFS(0);  // 0 1 2 3 4
    
    cout << "DFS (從 0 開始): ";
    g.DFS(0);  // 0 1 3 4 2
    
    return 0;
}
🚀 前往測驗