【Algorithm】图论入门

文章目录

  • 图论基础入门
    • 一、什么是图(Graph)
    • [二、图的存储结构(C++ 实现)](#二、图的存储结构(C++ 实现))
      • [1. 邻接表(Adjacency List)](#1. 邻接表(Adjacency List))
      • [2. 邻接矩阵(Adjacency Matrix)](#2. 邻接矩阵(Adjacency Matrix))
    • 三、图的遍历
      • [1. 深度优先搜索(DFS)](#1. 深度优先搜索(DFS))
      • [2. 广度优先搜索(BFS)](#2. 广度优先搜索(BFS))
    • [四、经典图算法(C++ 实现)](#四、经典图算法(C++ 实现))
      • [1. 拓扑排序(Topological Sort)------仅适用于有向无环图(DAG)](#1. 拓扑排序(Topological Sort)——仅适用于有向无环图(DAG))
        • [Kahn 算法(基于入度)](#Kahn 算法(基于入度))
      • [2. 最短路径算法](#2. 最短路径算法)
      • [3. 并查集(Union-Find)------用于连通性判断、Kruskal 算法](#3. 并查集(Union-Find)——用于连通性判断、Kruskal 算法)
    • 五、应用场景

图论基础入门

图论(Graph Theory)是计算机科学中的核心基础之一,被广泛应用于算法设计、工程系统、人工智能、编译器、网络通信、地图导航等多个方向。


一、什么是图(Graph)

图是一种由顶点(Vertex)和边(Edge)组成的数据结构,用于表示元素之间的关系。

分类:

  • 有向图(Directed Graph):边具有方向,如 A → B。
  • 无向图(Undirected Graph):边无方向,A 与 B 相互连接。
  • 带权图(Weighted Graph):边携带权重信息。
  • 稀疏图 / 稠密图:根据边的数量与顶点的比例判断。

二、图的存储结构(C++ 实现)

1. 邻接表(Adjacency List)

适用于稀疏图,节省空间。

cpp 复制代码
int n; // 顶点数量
vector<vector<int>> adj(n); // 无权图的邻接表

// 添加一条有向边 u → v
adj[u].push_back(v);

带权图:

cpp 复制代码
vector<vector<pair<int, int>>> adj(n); // pair<邻接点, 权重>

adj[u].emplace_back(v, weight);

2. 邻接矩阵(Adjacency Matrix)

适用于稠密图,占用空间大但查询更快。

cpp 复制代码
vector<vector<int>> matrix(n, vector<int>(n, 0));
matrix[u][v] = 1; // 表示 u → v 有边

三、图的遍历

1. 深度优先搜索(DFS)

cpp 复制代码
void dfs(int u, vector<vector<int>>& adj, vector<bool>& visited) {
    visited[u] = true;
    for (int v : adj[u]) {
        if (!visited[v]) {
            dfs(v, adj, visited);
        }
    }
}

2. 广度优先搜索(BFS)

cpp 复制代码
void bfs(int start, vector<vector<int>>& adj, vector<bool>& visited) {
    queue<int> q;
    visited[start] = true;
    q.push(start);

    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v : adj[u]) {
            if (!visited[v]) {
                visited[v] = true;
                q.push(v);
            }
        }
    }
}

四、经典图算法(C++ 实现)

1. 拓扑排序(Topological Sort)------仅适用于有向无环图(DAG)

Kahn 算法(基于入度)
cpp 复制代码
bool topoSort(int n, const vector<vector<int>>& adj, vector<int>& result) {
    vector<int> inDegree(n, 0);
    for (const auto& neighbors : adj)
        for (int v : neighbors) inDegree[v]++;
图论基础入门

    queue<int> q;
    for (int i = 0; i < n; ++i)
        if (inDegree[i] == 0) q.push(i);

    while (!q.empty()) {
        int u = q.front(); q.pop();
        result.push_back(u);
        for (int v : adj[u])
            if (--inDegree[v] == 0) q.push(v);
    }

    return result.size() == n; // false 表示有环
}

2. 最短路径算法

Dijkstra(适用于正权图)
cpp 复制代码
vector<int> dijkstra(int n, int start, const vector<vector<pair<int, int>>>& adj) {
    vector<int> dist(n, INT_MAX);
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

    dist[start] = 0;
    pq.emplace(0, start);

    while (!pq.empty()) {
        auto [d, u] = pq.top(); pq.pop();
        if (d > dist[u]) continue;
        for (auto [v, w] : adj[u]) {
            if (dist[u] + w < dist[v]) {
                dist[v] = dist[u] + w;
                pq.emplace(dist[v], v);
            }
        }
    }
    return dist;
}

3. 并查集(Union-Find)------用于连通性判断、Kruskal 算法

cpp 复制代码
struct UnionFind {
    vector<int> parent;
    UnionFind(int n) : parent(n) {
        iota(parent.begin(), parent.end(), 0);
    }

    int find(int x) {
        return parent[x] == x ? x : (parent[x] = find(parent[x]));
    }

    bool unite(int a, int b) {
        int pa = find(a), pb = find(b);
        if (pa == pb) return false;
        parent[pa] = pb;
        return true;
    }
};

五、应用场景

  • 编译依赖分析:如 Makefile 中的文件依赖。
  • 项目构建系统:如 CMake 中的模块拓扑。
  • 图数据库遍历:如 Neo4j 查询路径。
  • 地图导航系统:如最短路径搜索(Dijkstra、A*)。
  • 社交网络分析:好友推荐、社群划分。
  • 多线程任务调度系统:拓扑排序 + 优先级控制。
相关推荐
mxpan36 分钟前
VC++ 与 Golang 的协作:实现 HTTP 文件传输服务
c++·go·mfc
听风lighting37 分钟前
WevServer实现:异步日志写与HTTP连接
linux·网络·c++·网络协议·http·秋招·嵌入式面试
浮灯Foden2 小时前
算法-每日一题(DAY11)每日温度
开发语言·数据结构·c++·算法·leetcode·面试
闻缺陷则喜何志丹2 小时前
【并集查找】P10729 [NOISG 2023 Qualification] Dolls|普及+
c++·算法·图论·洛谷·并集查找
Yingye Zhu(HPXXZYY)3 小时前
P12894 [蓝桥杯 2025 国 Java B] 智能交通信号灯
c++·蓝桥杯
楼台的春风4 小时前
【Linux驱动开发 ---- 4_驱动开发框架和 API】
linux·c语言·c++·人工智能·驱动开发·嵌入式硬件·ubuntu
楼台的春风4 小时前
【Linux驱动开发 ---- 1.1_Linux 基础操作入门】
linux·c语言·c++·人工智能·驱动开发·嵌入式硬件·ubuntu
三体世界9 小时前
HTTPS加密原理
linux·开发语言·网络·c++·网络协议·http·https
杜子不疼.9 小时前
结构体的嵌套问题
c语言·c++