【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*)。
  • 社交网络分析:好友推荐、社群划分。
  • 多线程任务调度系统:拓扑排序 + 优先级控制。
相关推荐
羑悻的小杀马特1 小时前
CMake 全流程开发实战:从零开始掌握C++项目构建、测试到一键分发的完整解决方案
c++·cmake
T1an-11 小时前
C++版单例模式-现代化简洁写法
c++·单例模式
一拳一个呆瓜4 小时前
【MFC】对话框属性:Absolute Align(绝对对齐)
c++·mfc
爱编程的化学家5 小时前
代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和
数据结构·c++·算法·leetcode·双指针·哈希
许怀楠7 小时前
【主页介绍】
linux·c++·贪心算法·visual studio
木心爱编程9 小时前
C++链表实战:STL与手动实现详解
开发语言·c++·链表
离越词9 小时前
QTday1作业
c++·qt
HAH-HAH10 小时前
【蓝桥杯 2024 国 Java A】粉刷匠小蓝
c++·学习·数学·算法·职场和发展·蓝桥杯·组合数学
小吴同学·11 小时前
OPC Client第10讲:实现主界面;获取初始界面传来的所有配置信息config【C++读写Excel:xlnx;ODBC;缓冲区】
c++·wxwidgets
边疆.11 小时前
【C++】继承详解
开发语言·c++·继承