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

【数据结构与算法】图的基本概念与遍历

目录

一、图的基本概念

1.1 图的基本组成

1.2 图的分类

1.3 顶点的度数

1.4 路径与回路

1.5 子图与特殊图

二. 图的存储结构

2.1 邻接矩阵

2.2 邻接表

三、深度优先遍历

3.1 原理

3.2 实现步骤

3.3 代码实现

四、广度优先遍历

4.1 原理

4.2 实现步骤

4.3 代码实现

结语


一、图的基本概念

图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E)。

1.1 图的基本组成

顶点(Vertex)

  • 图的基本元素,代表具体的对象(如城市、网络节点等),通常用 V 表示顶点集合。

边(Edge)

  • 顶点之间的连接关系,代表对象间的关系(如道路、通信链路等),通常用 E 表示边集合。
  • 有向边:带有方向的边(用箭头表示),构成有向图
  • 无向边:没有方向的边,构成无向图

1.2 图的分类

  • 按边的方向性分类

  1. 无向图:所有边均为无向边,边记为 (u, v),且 (u, v)= (v, u) 。
  2. 有向图:至少存在一条有向边,边记为 <u, v>,表示从 u 到 v 的方向。

有向图

 

    无向图

  • 按边是否有权值分类

  1. 无权图:边仅表示连接关系,无权重(如是否可达)。
  2. 加权图:每条边带有数值权重(如距离、成本等)。

        加权图 

  • 按是否有重复边或自环分类

  1. 简单图:无重复边、无自环(顶点到自身的边)。
  2. 多重图:允许重复边(平行边)或自环。
  3. 完全图:任意两个顶点之间都有一条边(无向完全图有 (n(n-1)2) 条边,有向完全图有 (n(n-1)) 条边,n 为顶点数)。

1.3 顶点的度数

  • 无向图中的度数(Degree)

  1. 顶点 v 的度数是其连接的边数。
  2. 所有顶点度数之和等于边数的 2 倍(每条边被两个顶点各计数一次)。
  • 有向图中的度数
  1. 入度:指向顶点 v 的边数。
  2. 出度:顶点 v 发出的边数。
  3. 顶点度数 = 入度 + 出度。

1.4 路径与回路

  • 路径
  1. 顶点序列 (V1, V2, ......, Vk),其中相邻顶点由边连接。
  2. 简单路径:路径中所有顶点互不重复(除起点和终点可能相同)。
  • 回路

  1. 起点和终点相同的路径(长度 ≥ 1)。
  2. 简单回路:除起点和终点外,其余顶点互不重复的回路。
  • 连通性

  1. 无向图:若任意两顶点存在路径,则图是连通图;否则分为多个连通分量
  2. 有向图:若任意两顶点 (u -> v) 和 (v -> u) 均有路径,则为强连通图;否则分为强连通分量

1.5 子图与特殊图

  • 子图

  1. 顶点集和边集均为原图子集的图。
  • 二分图

  1. 顶点可分为两个不相交的集合,所有边均连接两个集合中的顶点(无同一集合内的边)。
  1. 无向图中,连通且无回路的图(顶点数 n,边数 (n-1))。
  2. 有向树:有向图中,仅有一个根节点(入度为 0),其余顶点入度为 1,且从根到所有顶点有唯一路径。

二. 图的存储结构

2.1 邻接矩阵

核心思想:

用一个二维矩阵 A 表示顶点之间的连接关系,矩阵大小为 (n * n)(n 为顶点数)

  1. 无权图:(A[i][j] = 1) 表示存在边 (i -> j)(有向图)或 ((i,j))(无向图),否则为 0。
  2. 加权图:(A[i][j] = w) 表示边的权重为 w,无边则设为无穷大。

优点

  • 访问边的时间复杂度为(O(1))(直接查矩阵)。
  • 适合表示稠密图(边数接近 (n^2))。

缺点

  • 空间复杂度为 (O(n^2)),存储稀疏图(边数少)时浪费空间。
  • 遍历一个顶点的所有邻接点需要扫描整行,效率低(O(n))。

2.2 邻接表

每个顶点对应一个列表,存储其相邻顶点(有向图存储出边,无向图存储所有邻接顶点)。

  • 无权图:链表中存储相邻顶点的编号。
  • 加权图:链表中存储二元组 ((邻接顶点, 权重))。

优点

  • 空间复杂度为 (O(n + e))(e 为边数),适合表示稀疏图
  • 遍历一个顶点的所有邻接点效率高(只需遍历其链表)。

缺点

  • 检查某条边是否存在需要遍历链表。
  • 无向图中每条边会被存储两次(在两个顶点的链表中)。

三、深度优先遍历

3.1 原理

深度优先搜索是一种图遍历算法,它沿着一条路径尽可能深入,直到无法继续为止,然后回溯到上一个节点,尝试其他路径。DFS 使用递归或栈实现,适合用于遍历所有可能的路径。

3.2 实现步骤

  1. 从起点开始
    • 标记当前节点为已访问。
    • 输出或处理当前节点。
  2. 递归访问邻接节点
    • 遍历当前节点的所有邻接节点。
    • 如果某个邻接节点未访问,递归调用 DFS。
  3. 回溯
    • 在递归返回时,回到上一个节点,继续探索其他未访问的邻接节点。

3.3 代码实现

#include <iostream>
#include <vector>void dfs(const std::vector<std::vector<int>>& graph, int node, std::vector<bool>& visited) {visited[node] = true;std::cout << node << " "; // 访问节点for (int i = 0; i < graph.size(); ++i) {if (graph[node][i] == 1 && !visited[i]) {dfs(graph, i, visited);}}
}int main() 
{// 示例图(邻接矩阵表示)std::vector<std::vector<int>> graph = {{0, 1, 1, 0, 0, 0},{1, 0, 0, 1, 1, 0},{1, 0, 0, 0, 0, 1},{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 1},{0, 0, 1, 0, 1, 0}};std::vector<bool> visited(graph.size(), false);std::cout << "DFS: ";dfs(graph, 0, visited); // 从节点 0 开始std::cout << std::endl;return 0;
}

四、广度优先遍历

4.1 原理

广度优先搜索是一种逐层遍历图的算法。它从起点开始,先访问所有直接邻接的节点,然后再访问这些节点的邻接节点。BFS 的特点是“逐层扩展”。

4.2 实现步骤

  1. 初始化队列
    • 将起点加入队列,并标记为已访问。
  2. 逐层遍历
    • 从队列中取出一个节点。
    • 输出或处理该节点。
    • 遍历当前节点的所有邻接节点:
      • 如果某个邻接节点未访问,将其加入队列,并标记为已访问。
  3. 重复
    • 继续从队列中取出节点,直到队列为空。

4.3 代码实现

#include <iostream>
#include <queue>
#include <vector>void bfs(const std::vector<std::vector<int>>& graph, int start) 
{int n = graph.size();std::vector<bool> visited(n, false);std::queue<int> q;visited[start] = true;q.push(start);while (!q.empty()) {int node = q.front();q.pop();std::cout << node << " "; // 访问节点for (int i = 0; i < n; ++i) {if (graph[node][i] == 1 && !visited[i]) {visited[i] = true;q.push(i);}}}
}int main() 
{// 示例图(邻接矩阵表示)std::vector<std::vector<int>> graph = {{0, 1, 1, 0, 0, 0},{1, 0, 0, 1, 1, 0},{1, 0, 0, 0, 0, 1},{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 1},{0, 0, 1, 0, 1, 0}};std::cout << "BFS: ";bfs(graph, 0); // 从节点 0 开始std::cout << std::endl;return 0;
}

结语

最近笔试老是最后一题出个图相关的,写这篇文章是为了复习图的相关知识点与遍历方法,临阵磨枪,希望在接下来的笔试中能应对这种题目。

相关文章:

【数据结构与算法】图的基本概念与遍历

目录 一、图的基本概念 1.1 图的基本组成 1.2 图的分类 1.3 顶点的度数 1.4 路径与回路 1.5 子图与特殊图 二. 图的存储结构 2.1 邻接矩阵 2.2 邻接表 三、深度优先遍历 3.1 原理 3.2 实现步骤 3.3 代码实现 四、广度优先遍历 4.1 原理 4.2 实现步骤 4.3 代码…...

MAE自监督大模型在医学报告生成中的应用

MAE自监督大模型在医学报告生成中的应用详解 一、核心技术原理与医学适配 MAE&#xff08;Masked Autoencoder&#xff09;通过掩膜重建策略&#xff0c;在医学影像领域展现出独特优势&#xff1a; 解剖结构理解&#xff1a;通过随机掩盖图像区域&#xff08;如75%的MRI切片&…...

Linux云服务器配置git开发环境

文章目录 1. 安装 git2. git clone3. git add .4. git commit -m 提交记录5. git push&#x1f351; 异常原因&#x1f351; 解决办法 6. git pull7. git log8. git rm9. git mv10. git status 1. 安装 git sudo yum install git -y2. git clone 此命令的作用是从远程仓库把代…...

Vue v-model 深度解析:实现原理与高级用法

一、v-model 的本质 v-model 是 Vue 中最常用的指令之一&#xff0c;它本质上是一个语法糖&#xff0c;用于在表单元素和自定义组件上实现双向数据绑定。在 Vue 2.x 和 Vue 3.x 中&#xff0c;v-model 的实现机制有所不同&#xff0c;但核心思想都是简化数据绑定的过程。 1.1…...

STM32F103单片机在不需要使用 JTAG 调试接口的情况下,释放引脚给其他功能使用。

最近调试STM32F103的时候&#xff0c;由于引脚比较紧张就用了PB3(SYS_JTDO-TRACESWO)引脚&#xff0c;带电下载完程序后&#xff0c;功能都是正常运行&#xff0c;但是断电再上电&#xff0c;PB3引脚就不受控制了&#xff0c;后来查了一下发现PB3不是普通的IO&#xff0c;需要关…...

手机浏览器IP归属地查询全指南:方法与常见问题解答

在当今数字化时代&#xff0c;手机浏览器已成为人们日常生活中不可或缺的工具之一。然而&#xff0c;在使用手机浏览器的过程中&#xff0c;有时我们需要了解当前网络连接的IP归属地信息&#xff0c;那么&#xff0c;手机浏览器IP归属地怎么查看呢&#xff1f;本文将详细介绍几…...

Microsoft Azure DevOps针对Angular项目创建build版本的yaml

Azure DevOps针对Angular项目创建build版本的yaml&#xff0c;并通过变量控制相应job的执行与否。 注意事项&#xff1a;代码前面的空格是通过Tab控制的而不是通过Space控制的。 yaml文件中包含一下内容&#xff1a; 1. 自动触发build 通过指定code branch使提交到此代码库的…...

Web 架构之负载均衡全解析

文章目录 一、引言二、思维导图三、负载均衡的定义与作用定义作用1. 提高可用性2. 增强性能3. 实现扩展性 四、负载均衡类型硬件负载均衡代表设备优缺点 软件负载均衡应用层负载均衡代表软件优缺点 网络层负载均衡代表软件优缺点 五、负载均衡算法轮询算法&#xff08;Round Ro…...

Linux系统管理与编程16:PXE自动化安装部署centos7.9操作系统

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 0.准备 1&#xff09;防火墙和SELinux systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i s/^SELINUX.*/SELINUXdisabled/ /etc/selinux/config (很不好的…...

金丝雀/灰度/蓝绿发布的详解

以下是 金丝雀发布、灰度发布 和 蓝绿发布 的详细解析&#xff0c;涵盖核心原理、技术实现、适用场景及实际案例&#xff1a; 1. 金丝雀发布 (Canary Release) 核心原理 渐进式流量切换&#xff1a;将新版本部署到生产环境后&#xff0c;逐步将用户流量从旧版本迁移到新版本&…...

如何通过ABAP获取SAP生产订单的目标成本

SAP存储生产订单成本的主要底表包括&#xff1a; COBK: CO凭证表头COEP: CO凭证行项目COSS: 来自CO内部的汇总数据COSP: 来自CO外部部的汇总数据 先说结论&#xff1a;SAP 对生产订单的目标成本是没有保存到底表的。那么如何通过代码的方式获取呢&#xff1f; K_KKB_KKBCS_O…...

git 多个提交记录合并为一个

1.场景 有时候用devops等平台测试问题&#xff0c;需要多次修改小的记录提交&#xff0c;但是最终我们在合并主干的时候不想留那么多乱七八糟的记录&#xff0c;就需要在此分支合并这些提交记录&#xff0c;再合并到主干。 2.交互式变基 2.1 确定要合并的提交范围 # 查看最近…...

深入理解栈数据结构(Java实现):从原理到实战应用

在计算机科学的世界里&#xff0c;数据结构是构建高效程序的基石&#xff0c;而栈作为其中最基础且应用广泛的一种数据结构&#xff0c;其独特的 “后进先出&#xff08;LIFO&#xff09;” 特性&#xff0c;使其在众多领域发挥着关键作用。从算法设计到编译器实现&#xff0c;…...

支付宝 SEO 优化:提升小程序曝光与流量的完整指南

在拥有庞大用户基数的支付宝平台上&#xff0c;小程序已成为商家触达用户、提供服务的重要渠道。然而&#xff0c;随着平台上小程序数量的快速增长&#xff0c;如何在激烈的竞争中脱颖而出&#xff0c;获得更多的曝光和流量&#xff0c;成为每个开发者和运营者必须面对的关键挑…...

【leetcode100】最长重复子数组

1、题目描述 给两个整数数组 nums1 和 nums2 &#xff0c;返回 两个数组中 公共的 、长度最长的子数组的长度 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,3,2,1], nums2 [3,2,1,4,7] 输出&#xff1a;3 解释&#xff1a;长度最长的公共子数组是 [3,2,1] 。示例 2&…...

代码随想录算法训练营第五十六天| 图论2—卡码网99. 岛屿数量(dfs bfs)

假期归来继续刷题&#xff0c;图论第二天&#xff0c;主要是进一步熟悉dfs 和 bfs 的运用。 99. 岛屿数量&#xff08;dfs&#xff09; 99. 岛屿数量 ACM模式还是需要练&#xff0c;不过现在输入输出的感觉已经比较熟悉了。首先是要按照输入搭建一个grid&#xff0c;然后有一…...

源码示例:使用SpringBoot+Vue+ElementUI+UniAPP技术组合开发一套小微企业ERP系统

目录 一、系统架构设计 1、技术分层 2、开发环境 二、快速开发实践 1、后端搭建&#xff08;Spring Boot&#xff09; 2、前端管理端&#xff08;VueElementUI&#xff09; 3、移动端开发&#xff08;UniAPP&#xff09; 三、关键集成方案 1、统一接口处理 2、跨平台…...

基于Django框架的股票分红数据爬虫和展示系统

项目截图 一、项目简介 本项目是一个基于 Django 框架的股票分红数据爬虫和展示系统。它可以从东方财富网站爬取股票分红数据&#xff0c;并将数据存储到 Django 数据库中&#xff0c;同时提供数据查询、导出和图表展示功能。该系统为用户提供了一个方便的平台&#xff0c;用于…...

QT高级(1)QTableView自定义委托集合,一个类实现若干委托

自定义委托集合 1同系列文章2 功能3 源码 1同系列文章 QT中级&#xff08;1&#xff09;QTableView自定义委托&#xff08;一&#xff09;实现QSpinBox、QDoubleSpinBox委托 QT中级&#xff08;2&#xff09;QTableView自定义委托&#xff08;二&#xff09;实现QProgressBar委…...

kubectl系列(十一):top 查询pod连接数

在 Kubernetes 中&#xff0c;kubectl top 命令默认仅支持查看 Pod 或节点的 CPU/内存资源使用情况&#xff0c;并不直接提供 TCP 连接数的统计功能。若要获取 Pod 的 TCP 连接数&#xff0c;需结合其他工具和方法。以下是具体实现方案&#xff1a; 1. 直接进入容器查看 TCP 连…...

关于Spring

目录 事务篇 事务篇 先说结论 Spring事务实际上依赖的是Transactional接口和数据库的事务实现。 举个例子说&#xff0c;比如我们现在有一个**Service1类&#xff0c;这个类的方法MethodA执行一个向表A中插入数据&#xff1b;还有一个**Service2类&#xff0c;这个类的方法M…...

小家电专用WD5201 非隔离AC-DC稳压器|宽压80-305V|三档输出2.7/3.3/5V|多重安全保护

小家电专用WD5201 AC-DC稳压器&#xff5c;宽压80-305V&#xff5c;三档输出2.7/3.3/5V&#xff5c;多重安全保护 &#x1f4a5; WD5201&#xff0c;小家电电源的智能“稳压卫士”&#xff01; ✨ 核心卖点&#xff1a; ✅ 宽压兼容&#xff1a;输入 80-305V AC&#xff0c;电网…...

Docker 核心目录结构

1. Docker 核心目录结构 数据存储目录 默认根目录&#xff1a;/var/lib/docker Docker 所有运行时数据&#xff08;镜像、容器、卷、网络配置等&#xff09;的默认存储位置。 bash 复制 下载 # 查看 Docker 数据根目录 docker info | grep "Docker Root Dir" # 输出…...

源码分析之Leaflet中的LayerGroup

概述 LayerGroup是一个图层组&#xff0c;通过继承Layer基类&#xff0c;提供了一种管理多个图层&#xff08;如标记、多边形等&#xff09;的容器机制&#xff0c;比如地图的添加/移除操作等。 源码分析 源码实现 LayerGroup的源码实现如下&#xff1a; export var Layer…...

小芯片大战略:Chiplet技术如何重构全球半导体竞争格局?

在科技飞速发展的今天&#xff0c;半导体行业作为信息技术的核心领域之一&#xff0c;其发展速度和创新水平对全球经济的发展具有举足轻重的影响。然而&#xff0c;随着芯片制造工艺的不断进步&#xff0c;传统的单片集成方式逐渐遇到了技术瓶颈&#xff0c;如摩尔定律逐渐逼近…...

普通IT的股票交易成长史--股价起伏的真相-缺口(2)

声明&#xff1a;本文章的内容只是自己学习的总结&#xff0c;不构成投资建议。价格行为理论学习可参考简介中的几位&#xff0c;感谢他们的无私奉献。 送给自己的话&#xff1a; 仓位就是生命&#xff0c;绝对不能满仓&#xff01;&#xff01;&#xff01;&#xff01;&…...

MindSpore框架学习项目-ResNet药物分类-模型优化

目录 5.模型优化 5.1模型优化 6.结语 参考内容&#xff1a; 昇思MindSpore | 全场景AI框架 | 昇思MindSpore社区官网 华为自研的国产AI框架&#xff0c;训推一体&#xff0c;支持动态图、静态图&#xff0c;全场景适用&#xff0c;有着不错的生态 本项目可以在华为云modelar…...

基于阿里云DataWorks的物流履约时效离线分析

基于阿里云DataWorks的物流履约时效离线分析2. 数仓模型构建 ORC和Parquet区别&#xff1a; 压缩率与查询性能 压缩率 ORC通常压缩率更高&#xff0c;文件体积更小&#xff0c;适合存储成本敏感的场景。 Parquet因支持更灵活的嵌套结构&#xff0c;压缩率略…...

Kubernetes(k8s)学习笔记(八)--KubeSphere定制化安装

1执行下面的命令修改上一篇中yaml文件来实现定制化安装devops kubectl edit cm -n kubesphere-system ks-installer 主要是将devops几个配置由False改为True 然后使用下面的命令查看安装日志 kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l …...

养生:为健康生活筑牢根基

养生并非遥不可及的目标&#xff0c;而是贯穿于日常生活的点滴之中。从饮食、运动到心态调节&#xff0c;每一个环节都对我们的健康有着重要意义。以下为你详细介绍养生的实用策略&#xff0c;助力你开启健康生活模式。 饮食养生&#xff1a;科学搭配&#xff0c;滋养生命 合…...