当前位置: 首页 > news >正文

C++-----图

一、图的结构

在 C++ 中,图可以用多种结构表示,常见的有邻接矩阵和邻接表。

邻接矩阵

使用二维数组 adjMatrix 来表示图中顶点之间的连接关系。对于无向图,如果 adjMatrix[i][j] 不为零,则表示顶点 i 和顶点 j 之间存在边;对于有权图,adjMatrix[i][j] 的值可以表示边的权重。对于无权图,可以用 1 表示有边,0 表示无边。

#include <iostream>
#include <vector>class GraphAdjMatrix {
private:int numVertices;std::vector<std::vector<int>> adjMatrix;
public:// 构造函数,初始化邻接矩阵GraphAdjMatrix(int vertices) : numVertices(vertices), adjMatrix(vertices, std::vector<int>(vertices, 0)) {}// 添加边void addEdge(int src, int dest, int weight = 1) {if (src >= 0 && src < numVertices && dest >= 0 && dest < numVertices) {adjMatrix[src][dest] = weight;// 对于无向图,添加反向边adjMatrix[dest][src] = weight; }}// 打印邻接矩阵void print() {for (int i = 0; i < numVertices; ++i) {for (int j = 0; j < numVertices; ++j) {std::cout << adjMatrix[i][j] << " ";}std::cout << std::endl;}}
};
邻接表

使用一个数组或向量,其中每个元素存储一个链表或向量,存储与该顶点相连的顶点。对于有权图,可以存储一个包含顶点和权重的结构体或 pair

#include <iostream>
#include <vector>class GraphAdjList {
private:int numVertices;std::vector<std::vector<int>> adjList;
public:// 构造函数,初始化邻接表GraphAdjList(int vertices) : numVertices(vertices), adjList(vertices) {}// 添加边void addEdge(int src, int dest) {adjList[src].push_back(dest);// 对于无向图,添加反向边adjList[dest].push_back(src); }// 打印邻接表void print() {for (int i = 0; i < numVertices; ++i) {std::cout << i << " -> ";for (int neighbor : adjList[i]) {std::cout << neighbor << " ";}std::cout << std::endl;}}
};

二、图的遍历

图的遍历有深度优先搜索(DFS)和广度优先搜索(BFS)两种常见方法。

深度优先搜索 (DFS)

DFS 是一种递归算法,从起始顶点开始,尽可能深地访问图的分支。

#include <iostream>
#include <vector>class GraphDFS {
private:int numVertices;std::vector<std::vector<int>> adjList;std::vector<bool> visited;// 辅助函数,进行深度优先搜索void dfsUtil(int vertex) {visited[vertex] = true;std::cout << vertex << " ";for (int neighbor : adjList[vertex]) {if (!visited[neighbor]) {dfsUtil(neighbor);}}}
public:GraphDFS(int vertices) : numVertices(vertices), adjList(vertices), visited(vertices, false) {}// 添加边void addEdge(int src, int dest) {adjList[src].push_back(dest);// 对于无向图,添加反向边adjList[dest].push_back(src); }// 执行深度优先搜索void dfs(int startVertex) {dfsUtil(startVertex);}
};
广度优先搜索 (BFS)

BFS 是一种迭代算法,从起始顶点开始,逐层访问图的顶点。

#include <iostream>
#include <vector>
#include <queue>class GraphBFS {
private:int numVertices;std::vector<std::vector<int>> adjList;std::vector<bool> visited;public:GraphBFS(int vertices) : numVertices(vertices), adjList(vertices), visited(vertices, false) {}// 添加边void addEdge(int src, int dest) {adjList[src].push_back(dest);// 对于无向图,添加反向边adjList[dest].push_back(src); }// 执行广度优先搜索void bfs(int startVertex) {std::queue<int> q;visited[startVertex] = true;q.push(startVertex);while (!q.empty()) {int vertex = q.front();q.pop();std::cout << vertex << " ";for (int neighbor : adjList[vertex]) {if (!visited[neighbor]) {visited[neighbor] = true;q.push(neighbor);}}}}
};

三、最短路径算法

有多种最短路径算法,以下是 Dijkstra 算法的实现。

Dijkstra 算法

用于求解单源最短路径问题,适用于边权为非负的图。

#include <iostream>
#include <vector>
#include <queue>
#include <climits>class GraphDijkstra {
private:int numVertices;std::vector<std::vector<std::pair<int, int>>> adjList; // pair: (neighbor, weight)std::vector<int> dijkstra(int src) {std::vector<int> dist(numVertices, INT_MAX);dist[src] = 0;std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> pq;pq.push({0, src});while (!pq.empty()) {int u = pq.top().second;pq.pop();for (auto neighbor : adjList[u]) {int v = neighbor.first;int weight = neighbor.second;if (dist[u] + weight < dist[v]) {dist[v] = dist[u] + weight;pq.push({dist[v], v});}}}return dist;}
public:GraphDijkstra(int vertices) : numVertices(vertices), adjList(vertices) {}// 添加边void addEdge(int src, int dest, int weight) {adjList[src].push_back({dest, weight});}// 打印从源点出发的最短路径void printShortestPaths(int src) {std::vector<int> dist = dijkstra(src);for (int i = 0; i < numVertices; ++i) {std::cout << "Distance from " << src << " to " << i << " is " << dist[i] << std::endl;}}
};

四、搜索网页算法(PageRank 算法)

PageRank 算法用于评估网页的重要性。

#include <iostream>
#include <vector>
#include <cmath>class WebGraphPageRank {
private:int numPages;std::vector<std::vector<bool>> adjMatrix;std::vector<double> pageRank;double dampingFactor = 0.85;double tolerance = 0.0001;bool isConverged(const std::vector<double>& oldPR, const std::vector<double>& newPR) {for (int i = 0; i < numPages; ++i) {if (std::abs(oldPR[i] - newPR[i]) > tolerance) {return false;}}return true;}void updatePageRank() {std::vector<double> newPR(numPages, 0);for (int i = 0; i < numPages; ++i) {for (int j = 0; j < numPages; ++j) {if (adjMatrix[j][i]) {int outDegree = 0;for (int k = 0; k < numPages; ++k) {if (adjMatrix[j][k]) outDegree++;}newPR[i] += pageRank[j] / outDegree;}}newPR[i] = (1 - dampingFactor) / numPages + dampingFactor * newPR[i];}pageRank = newPR;}public:WebGraphPageRank(int pages) : numPages(pages), adjMatrix(pages, std::vector<bool>(pages, false)), pageRank(pages, 1.0 / pages) {}// 添加网页之间的链接void addLink(int src, int dest) {if (src >= 0 && src < numPages && dest >= 0 && dest < numPages) {adjMatrix[src][dest] = true;}}// 计算 PageRankvoid computePageRank() {std::vector<double> prevPR = pageRank;do {updatePageRank();} while (!isConverged(prevPR, pageRank));}// 打印 PageRank 值void printPageRank() {for (int i = 0; i < numPages; ++i) {std::cout << "Page " << i << " : " << pageRank[i] << std::endl;}}
};

解释

  • 图的结构表示

    • 邻接矩阵:使用二维数组,易于理解和实现,对于稠密图空间效率较高,但对于稀疏图会浪费空间。
    • 邻接表:使用数组加链表(或向量),对于稀疏图空间效率更高,但查找边时可能需要遍历链表。
  • 图的遍历

    • DFS:使用递归方式,先访问当前顶点,然后递归访问其邻居,直到无法继续深入,再回溯。
    • BFS:使用队列,先访问当前顶点,将邻居入队,按入队顺序依次访问,实现层次遍历。
  • 最短路径算法(Dijkstra)

    • 利用优先队列(最小堆)存储距离源点的距离,不断选取距离最小的顶点,更新其邻居的距离。
  • 搜索网页算法(PageRank)

    • 基于网页之间的链接关系,迭代更新每个网页的重要性得分,直到收敛。根据链接的入度和出度,结合阻尼因子计算得分。

使用示例

int main() {// 邻接矩阵示例GraphAdjMatrix g1(5);g1.addEdge(0, 1, 10);g1.addEdge(0, 2, 20);g1.addEdge(1, 2, 30);g1.addEdge(2, 3, 40);g1.print();// 邻接表示例GraphAdjList g2(5);g2.addEdge(0, 1);g2.addEdge(0, 2);g2.addEdge(1, 2);g2.addEdge(2, 3);g2.print();// DFS 示例GraphDFS g3(5);g3.addEdge(0, 1);g3.addEdge(0, 2);g3.addEdge(1, 2);g3.addEdge(2, 3);std::cout << "DFS: ";g3.dfs(0);std::cout << std::endl;// BFS 示例GraphBFS g4(5);g4.addEdge(0, 1);g4.addEdge(0, 2);g4.addEdge(1, 2);g4.addEdge(2, 3);std::cout << "BFS: ";g4.bfs(0);std::cout << std::endl;// Dijkstra 算法示例GraphDijkstra g5(5);g5.addEdge(0, 1, 10);g5.addEdge(0, 2, 20);g5.addEdge(1, 2, 30);g5.addEdge(2, 3, 40);g5.printShortestPaths(0);// PageRank 算法示例WebGraphPageRank wg(5);wg.addLink(0, 1);wg.addLink(0, 2);wg.addLink(1, 2);wg.addLink(2, 0);wg.addLink(2, 3);wg.addLink(3, 4);wg.addLink(4, 0);wg.computePageRank();wg.printPageRank();return 0;
}

总结

  • 图是一种强大的数据结构,可用于解决许多现实世界的问题,如网络路由、社交网络分析、网页搜索等。
  • 选择合适的图表示方法(邻接矩阵或邻接表)取决于图的稀疏程度。
  • 不同的遍历算法(DFS 和 BFS)适用于不同的场景,DFS 适合寻找路径和解决可达性问题,BFS 适合寻找最短路径和层次遍历。
  • 最短路径算法(如 Dijkstra)可以找到图中源点到其他点的最短路径,适用于边权非负的情况。
  • 搜索网页算法(如 PageRank)可评估网页的重要性,通过不断迭代更新得分,考虑网页之间的链接结构。
    在这里插入图片描述

相关文章:

C++-----图

一、图的结构 在 C 中&#xff0c;图可以用多种结构表示&#xff0c;常见的有邻接矩阵和邻接表。 邻接矩阵 使用二维数组 adjMatrix 来表示图中顶点之间的连接关系。对于无向图&#xff0c;如果 adjMatrix[i][j] 不为零&#xff0c;则表示顶点 i 和顶点 j 之间存在边&#x…...

mysql 数据库迁移到达梦数据库

1.windows安装达梦数据库&#xff0c;去官网下载 dm8 进行安装&#xff0c;安装后&#xff0c;可以使用管理工具管理数据 使用迁移工具对数据进行迁移&#xff1b; 2.使用php 或者 thinkphp连接达梦数据库 2.1、先PHP开启DM扩展 从达梦数据库安装目录下drivers/php_pdo 复制对…...

【记录】使用R2 CDN替换本地项目图片以加速图片加载

将图片存储到 Cloudflare 的存储桶中&#xff0c;并通过其提供的公共 URL 来替换代码中的本地路径&#xff0c;可以减小项目中打包的图片文件体积 实现方法的详细步骤&#xff1a; 1. 上传图片到 Cloudflare 的存储桶 &#xff08;1&#xff09;登录 Cloudflare Dashboard&am…...

12.13[java exp4][debug]nginx 500,究极未解之谜,出自重启,解决自重启,迷???

pro1 pro2?????????未解之谜&#xff0c;究极未解之谜&#xff1f;&#xff1f;&#xff1f;&#xff1f; 就是 auth_request http://auth_server/auth/check;接受不到&#xff0c;auth_server无法受到请求&#xff0c;就完全没收到&#xff1f;但是/auth/login等直接…...

Disruptor 高性能环形消息框架

官方文档&#xff1a;Disruptor 1. 简介 Disruptor是一个高性能的互进程&#xff08;Inter-process&#xff09;和多线程&#xff08;Multi-threaded&#xff09;消息处理库&#xff0c;由LMAX交易所开发&#xff0c;用于在Java虚拟机&#xff08;JVM&#xff09;上实现高性能…...

Python列表(二)

方式三&#xff1a; 创建对应的枚举对象 概念&#xff1a;通过枚举函数&#xff0c;生成一个新的对象 作用&#xff1a;函数用于将一个可遍历的数据对象&#xff08;如列表、元组或字符串&#xff09;组合为一个索引序列 同时列出数据下标和数据 #生成枚举对象 values [&…...

计算机网络:应用层 —— 网络应用模式

文章目录 客户—服务器方式和对等方式客户/服务器方式 (C/S方式)工作流程特点 对等方式 (P2P方式)工作流程P2P 应用特点 客户—服务器方式和对等方式 网络应用程序运行在处于网络边缘的不同的端系统上&#xff0c;通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用…...

@Repository注解和@mapper的区别

1. Repository 注解 通俗解释&#xff1a; 你可以把 Repository 注解想象成是一个专门负责管理数据库操作的 “仓库管理员”。这个管理员主要负责和数据库打交道&#xff0c;就像管理一个大仓库一样&#xff0c;他会进行各种操作&#xff0c;比如把货物&#xff08;数据&#x…...

解锁成长密码:探寻刻意练习之道

刻意练习&#xff0c;真有那么神&#xff1f; 在生活中&#xff0c;你是否有过这样的困惑&#xff1a;每天苦练英语口语&#xff0c;可一到交流时还是支支吾吾&#xff1b;埋头苦学吉他&#xff0c;却总是卡在几个和弦转换上&#xff1b;工作多年&#xff0c;业务能力却似乎陷入…...

cuda-cuDnn

cuda sudo /bin/sh cuda_11.7.0_515.43.04_linux.run cudnn cuDNN Archive | NVIDIA Developer Linux 系统 CUDA 多版本共存以及切换 – 颢天 安装cuda # 如果已经安装过驱动&#xff0c;驱动不需要再安装&#xff0c;取消勾选 安装cuDNN&#xff0c;cuda-cuDNN对应关系见…...

如何使用Python和PIL库生成带竖排文字的封面图像

在今天的博客中&#xff0c;我们将学习如何使用Python和PIL&#xff08;Pillow&#xff09;库生成一个简单而有创意的封面图像。我们将创建一个背景图像&#xff0c;并在其上绘制带有竖排文字的标题和副标题&#xff0c;最后再添加一些装饰性元素如星星和萤火虫。这个教程适合初…...

低代码开发 实战转型案例一览

数字浪潮澎湃&#xff0c;企业应用开发需求呈井喷之势。传统全栈开发虽底蕴深厚&#xff0c;然其漫长周期与高昂成本&#xff0c;难以追赶市场快速交付的急切步伐。无代码与低代码平台顺势崛起&#xff0c;宛如暗夜明灯&#xff0c;吸引非技术人员纷至沓来&#xff0c;投身应用…...

SQL Server中FIRST_VALUE和 LAST_VALUE窗口函数允许在一个指定的窗口内返回第一个或最后一个值

在 SQL Server 中&#xff0c;FIRST_VALUE 和 LAST_VALUE 是用于窗口函数&#xff08;Window Functions&#xff09;的两个非常有用的函数。它们允许你在一个指定的窗口内返回第一个或最后一个值。这两个函数通常与 OVER 子句一起使用&#xff0c;以定义窗口的范围和排序规则。…...

机器学习-高斯混合模型

文章目录 高斯混合模型对无标签的数据集&#xff1a;使用高斯混合模型进行聚类对有标签的数据集&#xff1a;使用高斯混合模型进行分类总结 高斯混合模型 对无标签的数据集&#xff1a;使用高斯混合模型进行聚类 对有标签的数据集&#xff1a;使用高斯混合模型进行分类 总结...

微信V3支付报错 平台证书及平台证书序列号

1.平台证书及平台证书序列号设置错误报错&#xff1a; 错误1&#xff1a; Verify the response’s data with: timestamp1735184656, noncea5806b8cabc923299f8db1a174f3a4d0, signatureFZ5FgD/jtt4J99GKssKWKA/0buBSOAbWcu6H52l2UqqaJKvrsNxvodB569ZFz5G3fbassOQcSh5BFq6hvE…...

41.欠采样技术下变频不能用与跨两个nyquist的情况下

当接收到的信号位于同一nyquist区间时&#xff0c;信号被成功的折叠到了第一Nyquist区间中。 当接收信号位于两个或多个采样区间时&#xff0c;最后多个区间的信号都会被折叠到第一Nyquist区间中造成信号的重叠。...

20241227通过配置nomodeset参数解决更新grub之后,ubuntu20.04.5无法启动的问题

20241227通过配置nomodeset参数解决更新grub之后&#xff0c;ubuntu20.04.5无法启动的问题 2024/12/27 17:34 0.397475]pci0000:00:07.0:DPC:RPPI0 l0gsize 0 is invalid dev/nvmeon1p9:clean,251849/4276224 files,3266309/17089792 blocks 缘起&#xff1a;公司电脑要安装加密…...

从 GitLab.com 到 JihuLab.com 的迁移指南

本文分享从 GitLab.com 到 JihuLab.com 的迁移指南。 近期&#xff0c;GitLab Inc. 针对其 SaaS 产品做了限制&#xff0c;如果被判定为国内用户&#xff0c;则会建议使用其在国内的发布版本极狐GitLab。从 GitLab SaaS 产品&#xff08;GitLab.com&#xff09;迁移到极狐GitL…...

深度学习中的并行策略概述:2 Data Parallelism

深度学习中的并行策略概述&#xff1a;2 Data Parallelism 数据并行&#xff08;Data Parallelism&#xff09;的核心在于将模型的数据处理过程并行化。具体来说&#xff0c;面对大规模数据批次时&#xff0c;将其拆分为较小的子批次&#xff0c;并在多个计算设备上同时进行处…...

Python大数据可视化:基于Python对B站热门视频的数据分析与研究_flask+hive+spider

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 排行榜界面 系统管理界面 看板展示 摘要 本项目以对B站热…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...