【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*)。
  • 社交网络分析:好友推荐、社群划分。
  • 多线程任务调度系统:拓扑排序 + 优先级控制。
相关推荐
xier_ran38 分钟前
邻接矩阵的 k 次幂意味着什么?从图论到路径计数的直观解释
算法·图论
想唱rap2 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
yuyanjingtao3 小时前
CCF-GESP 等级考试 2024年9月认证C++四级真题解析
c++·算法·青少年编程·gesp·csp-j/s
光头闪亮亮3 小时前
curl库应用-c++客户端示例及golang服务端应用示例
c++·go
Lei_3359673 小时前
[算法]背包DP(01背包、完全背包问题、多重背包、分组背包、混合背包问题、有依赖的背包问题等)
c++·算法
wolfseek4 小时前
opencv模版匹配
c++·人工智能·opencv·计算机视觉
仰泳的熊猫4 小时前
LeetCode:773. 滑动谜题
数据结构·c++·算法·leetcode
千里马-horse5 小时前
Boost.Iostreams 简介
开发语言·c++·boost
陌路205 小时前
C17值类别概念
开发语言·c++
shark_dev5 小时前
C++新特性—— 智能指针(shared_ptr/unique_ptr/weak_ptr)
c++