【C++】图论:基础理论与实际应用深入解析

你好 (=´ω`=)

已经是2026年啦,我们已经度过了我们一生中唯一一个立方和年了....

因为某种原因,跨年那天没有发文章,不过我的作品突破了50赞。

这里还是要感谢大家一直以来的支持,祝大家2026也要开开心心哦 φ(>ω<*)

目录

你好,图论

什么是图?

在C++中表示图

邻接表:朋友链表

邻接矩阵:关系表

拜访图中的每一个顶点

深度优先搜索(DFS)

广度优先搜索(BFS)

一些简单的图论算法

最短路径(Dijkstra算法)

从一个小例子开始

给初学者的建议

最后想说


你好,图论

如果你正在学习C++,又对算法感兴趣,我想你已经听说过 "图论" 这个名字了。

也许你觉得它复杂,但其实它很温柔-一就像我们用代码描述世界的一种安静方式。


什么是图?

图,其实就是一些点和连接这些点的线。

点我们叫 "顶点" ,线我们叫 "边" 。

现实中有太多图的身影了:

  • 你的微信好友关系是一个图
  • 地图上的地点和道路是一个图
  • 网页之间的链接也是一个图

在C++中表示图

我们有几种简单的方法来告诉计算机,我们的图是什么样子的。

邻接表:朋友链表

为每个顶点准备一个列表,记录它的所有邻居:

cpp 复制代码
#include <vector>
using namespace std;

// 创建有5个顶点的图
int n = 5;
vector<vector<int>> graph(n);

// 添加一条从顶点0到顶点1的边
graph[0].push_back(1);

// 如果需要无向图,就添加两次
graph[0].push_back(1);
graph[1].push_back(0);

邻接表很节省空间,特别适合朋友不太多的顶点。

邻接矩阵:关系表

用一个二维表格记录每对顶点是否相连:

cpp 复制代码
#include <vector>
using namespace std;

int n = 5;
// 创建n×n的表格,初始为false
vector<vector<bool>> matrix(n, vector<bool>(n, false));

// 连接顶点0和1
matrix[0][1] = true;
// 如果是无向图
matrix[1][0] = true;

// 检查0和1是否相连
if (matrix[0][1]) {
    cout << "0和1是相连的" << endl;
}

拜访图中的每一个顶点

深度优先搜索(DFS)

沿着一条路走到底,再慢慢返回:

cpp 复制代码
void dfs(int node, vector<bool>& visited, vector<vector<int>>& graph) {
    visited[node] = true;
    cout << "拜访顶点: " << node << endl;
    
    for (int neighbor : graph[node]) {
        if (!visited[neighbor]) {
            dfs(neighbor, visited, graph);
        }
    }
}

广度优先搜索(BFS)

一层一层地向外探索:

cpp 复制代码
#include <queue>

void bfs(int start, vector<vector<int>>& graph) {
    int n = graph.size();
    vector<bool> visited(n, false);
    queue<int> q;
    
    visited[start] = true;
    q.push(start);
    
    while (!q.empty()) {
        int current = q.front();
        q.pop();
        cout << "拜访顶点: " << current << endl;
        
        for (int neighbor : graph[current]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}

一些简单的图论算法

最短路径(Dijkstra算法)

找到从一个点到其他所有点的最短距离:

cpp 复制代码
#include <queue>
#include <climits>

vector<int> dijkstra(int start, vector<vector<pair<int, int>>>& graph) {
    int n = graph.size();
    vector<int> distance(n, INT_MAX);
    priority_queue<pair<int, int>> pq;  // 优先队列
    
    distance[start] = 0;
    pq.push({0, start});
    
    while (!pq.empty()) {
        int dist = -pq.top().first;  // 取负值实现最小堆
        int node = pq.top().second;
        pq.pop();
        
        if (dist > distance[node]) continue;
        
        for (auto& edge : graph[node]) {
            int neighbor = edge.first;
            int weight = edge.second;
            
            if (distance[node] + weight < distance[neighbor]) {
                distance[neighbor] = distance[node] + weight;
                pq.push({-distance[neighbor], neighbor});
            }
        }
    }
    
    return distance;
}

从一个小例子开始

让我们实现一个简单的社交网络分析:

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>

class SocialNetwork {
private:
    vector<vector<int>> friends;
    
public:
    SocialNetwork(int n) : friends(n) {}
    
    void addFriendship(int a, int b) {
        friends[a].push_back(b);
        friends[b].push_back(a);
    }
    
    // 找到两个人的最短关系链长度
    int findConnectionLevel(int person1, int person2) {
        int n = friends.size();
        vector<bool> visited(n, false);
        queue<pair<int, int>> q;  // (人, 距离)
        
        visited[person1] = true;
        q.push({person1, 0});
        
        while (!q.empty()) {
            auto [current, dist] = q.front();
            q.pop();
            
            if (current == person2) {
                return dist;
            }
            
            for (int friendId : friends[current]) {
                if (!visited[friendId]) {
                    visited[friendId] = true;
                    q.push({friendId, dist + 1});
                }
            }
        }
        
        return -1;  // 没有找到连接
    }
};

给初学者的建议

  1. 从简单的开始:先理解邻接表和邻接矩阵
  2. 动手实现:不要只看代码,自己写一遍
  3. 画图帮助理解:在纸上画出小规模的图
  4. 调试观察:用小的测试数据跟踪程序执行

最后想说

图论并不像看起来那么难。

每个复杂的算法都是由简单的想法组成的。

在C++中实现图论算法,就像是教计算机如何观察和理解关系。

你可以从小的练习开始,比如计算你朋友圈中的共同好友,或者找出从宿舍到教室的所有路径。

一点一点地,你会发现图论其实是很有逻辑的,甚至是有点优美的。

希望这些简单的介绍能帮助你开始。

学习编程的路上,我们都慢慢来,每一步都算数。

如果您看到这里请点赞关注支持一下吧✧*。٩(ˊᗜˋ*)و✧*。

相关推荐
李泽辉_17 小时前
深度学习算法学习(五):手动实现梯度计算、反向传播、优化器Adam
深度学习·学习·算法
欧阳x天17 小时前
STL讲解(二)—string类的模拟实现
c++
带土117 小时前
2. Linux下FFmpeg C++音视频解码+推流开发
linux·c++·ffmpeg
星火开发设计17 小时前
C++ set 全面解析与实战指南
开发语言·c++·学习·青少年编程·编程·set·知识
李泽辉_17 小时前
深度学习算法学习(一):梯度下降法和最简单的深度学习核心原理代码
深度学习·学习·算法
꧁Q༒ོγ꧂17 小时前
算法详解---大纲
算法
m0_6038887117 小时前
Scaling Trends for Multi-Hop Contextual Reasoning in Mid-Scale Language Models
人工智能·算法·ai·语言模型·论文速览
Xの哲學17 小时前
Linux io_uring 深度剖析: 重新定义高性能I/O的架构革命
linux·服务器·网络·算法·边缘计算
scx2013100417 小时前
20260105 莫队总结
c++