数据结构——非线性结构(图)

2023-11-18

文章目录

一. 非线性结构的概述

在这里插入图片描述

二. 图的基本概念

1. 定义

在这里插入图片描述

2. 无向图、有向图

2.1 无向图

在这里插入图片描述

2.2 有向图

在这里插入图片描述

2.3 简单图

在这里插入图片描述

2.4 多重图

在这里插入图片描述

3. 顶点的度、出度、入度

3.1 对于无向图

在这里插入图片描述

3.2 对于有向图

在这里插入图片描述

4. 边的权、带权图 (网)

在这里插入图片描述

5. 点到点的关系

5.1 顶点与顶点之间的关系描述

在这里插入图片描述

5.2 连通的、强连通的、连通图、强连通图

在这里插入图片描述
如果本身就是连通图,则本身就是其连通分量,而非连通图的各个连通图作为其组成部分均为其连通分量


强连通图:任意顶点出发可以到达其余任意节点

  • 假设一个图有n个节点,如果边数小于n-1,那么此图必是非连通图
  • 一个图有n个顶点,并且有大于n-1条边,则此图一定有环

6. 图的局部

6.1 无向图子图、生成子图

在这里插入图片描述

6.2 有向图子图、生成子图

在这里插入图片描述

6.3 连通分量

在这里插入图片描述
极小连通子图:保证了连通,且有着最少的边数

6.4 强连通分量

在这里插入图片描述

7. 几种特殊形态的图

7.1 生成树

在这里插入图片描述

7.2 生成森林

在这里插入图片描述

7.3 无向完全图和有向完全图

在这里插入图片描述

7.4 稀疏图和稠密图

在这里插入图片描述

7.5 生成树和有向树

在这里插入图片描述

三. 图的存储

  • 要根据不同图的结构和算法,采用不同存储结构,以使的程序的效率最大化
  • 由于图的结构比较复杂,任意两个顶点之间都有可能存在联系,因此无法以数据元素在内存中的物理位置来表示元素之间的关系

1. 邻接矩阵法

1.1 定义

  • 顶点不分大小、主次,所以用一个一维数组存储图中顶点的信息
  • 边或弧由于是顶点之间的关系,用一个二维数组存储图中边的信息(这个二维数组称为邻接矩阵)

1.2 邻接矩阵存储有向图和无向图

在这里插入图片描述
在这里插入图片描述

1.3 邻接矩阵存储带权图(网)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 邻接矩阵法的性能分析

在这里插入图片描述

1.5 邻接矩阵法的性质

性质1:
在这里插入图片描述

性质2:
在这里插入图片描述

2. 邻接表法

2.1 来源

由于邻接矩阵是使用数组实现的顺序存储,空间复杂度高,不适合存储稀疏图。
在这里插入图片描述

2.2 定义(采用顺序存储和链式存储结合)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 邻接表法的性质

性质1:
在这里插入图片描述
性质2:
在这里插入图片描述

2.4 邻接表和邻接矩阵的比较

在这里插入图片描述
tip

  • 空间复杂度只与存储的节点数有关,与边数无关

3. 十字链表(只能存储有向图)

3.1 来源

在这里插入图片描述

3.2 定义

是有向图的一种链式存储结构:将邻接表和逆邻接表整合在一起

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 十字链表法性能分析

在这里插入图片描述

  • 十字链表中容易求得顶点的出度和入度
  • 图的十字链表表示是不唯一的,但一个十字链表表示确定一个图

4. 邻接多重表(只能存储无向图)

4.1 来源

在邻接表中,容易求得顶点和边的各种信息,但在邻接表中求两个顶点之间是否存在边而对边执行删除等操作时,需要分别在两个顶点的边表中遍历,效率较低

在这里插入图片描述

4.2 定义

邻接多重表是无向图的另一种链式存储结构

在这里插入图片描述
在这里插入图片描述

4.3 邻接多重表性能分析

在这里插入图片描述

5. 四种存储结构的比较

在这里插入图片描述

四. 图的基本操作

图的基本操作是独立于图的存储结构的。不同的存储结构,操作算法有着不同的的性能。

在这里插入图片描述

五. 图的遍历

1)什么是图的遍历?

  • 指从图中某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有节点访问一次且仅访问一次

2) 图遍历与树遍历的关系

  • 树遍历本质上也视为一种特殊的图遍历

3)为什么需要图的遍历

  • 为了求解图的连通性
  • 为了进行拓扑排序
  • 为了求关键路径

4)图遍历的关键是什么?

  • 为了避免同一顶点被访问多次,在遍历图的过程中必须记下已访问过的顶点(可设一个辅助数组visited[ ]标记顶点)

1. 广度优先搜索(BFS遍历)

1.1 概述

1)树的广度优先搜索

  • 也就是二叉树的层序遍历
  • 访问完第一层节点之后再访问第二层节点

2)图的广度优先搜索(Breadth-First-Search)

  • 是二叉树层次遍历算法的扩展
  • 从某个节点开始访问,访问完该节点后,访问与该节点相邻的且未被访问过的节点,再从这些访问过的节点出发,访问他们所有未被访问的相邻节点,直至所有节点被访问完为止。此时若图中还有节点未被访问,则另外选一个未被访问的节点作为起始节点,重复上面过程。

3)树和图的广度优先遍历的比较
在这里插入图片描述

广度优先遍历是一种分层查找过程,为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问的顶点的下一层顶点。

4)广度优先遍历序列
在这里插入图片描述

tip

  • 广度优先搜索以起始结点为中心,一层一层地向外层扩展遍历图的顶点,因此无法考虑到边权值,只适合求边权值相等的图的单源最短路径

1.2 复杂度分析

1)空间复杂度
在这里插入图片描述

2)时间复杂度
在这里插入图片描述

1.3 广度优先生成树

在这里插入图片描述
在这里插入图片描述
扩展:广度优先生成森林
在这里插入图片描述

2. 深度优先搜索(DFS遍历)

2.1 概述

1)树的深度优先遍历

  • 从根节点出发,能往更深处走就尽量往深处走。每当访问一个节点的时候,要检查是否还有与当前节点相邻的且没有被访问过的节点,如果有的话就往下一层钻。

2)图的深度优先遍历(Depth-First-Search)

  • 与树的先根遍历类似
  • 算法思想:首先访问图中某一起始顶点,然后由该顶点出发,访问与该顶点相邻且没有被访问的任意顶点w,在访问与w相邻且没有被访问的任意顶点x。当不能继续访问时,依次向后退到最近被访问的顶点,判断是否有邻接顶点被访问。
  • DFS算法是一个递归算法,需要借助一个递归工作栈,故其空间复杂度为O(|V|)。

3)深度优先遍历序列
在这里插入图片描述
在这里插入图片描述
tip

  • 利用深度优先遍历可以判断图G中是否存在回路。对于无向图来说,若深度优先遍历过程中遇到了回边,则必定存在环

2.2 复杂度分析

1)空间复杂度

在这里插入图片描述
2)时间复杂度
在这里插入图片描述

2.3 深度优先生成树

在这里插入图片描述
在这里插入图片描述

扩展:深度优先生成森林

  • 非连通,需要调用多次DFS函数

在这里插入图片描述

3. 图的遍历和图的连通性

图的遍历算法可以用来判断图的连通性

3.1 对于无向图

在这里插入图片描述

3.2 对于有向图

在这里插入图片描述

六. 图的应用

1. 最小生成(代价)树

1.1 概述

1) 来源

在这里插入图片描述

2) 定义

一个带权的图中(网),有n个顶点,用n-1条边把一个连通图连接起来,并要使的权值的和最小。
在这里插入图片描述

3) 性质

在这里插入图片描述
在这里插入图片描述

1.2 求最小生成树的两种算法

都是基于贪心算法策略

1) Prim算法

从某一个顶点出发,找一条与顶点集权值最小的边相连

算法思想:

  • 从顶点开始扩展最小生成树
  • 从某一个顶点开始构建生成树;每次将代价最小的新顶点纳入生成树,直到所有顶点都纳入为止
  • 算法的执行非常类似于寻找图的最短路径的Dijkstra算法

算法演示:

。。。见笔记

算法总结:

  • 同一个图最小生成树的方案可能不只一个,但是最小代价是相同的
  • 不同起点图构成的生成树可能方案是相同的

2) Kruskal算法

每次选边权值最小的相连,顶点已连接的,边就不需要连接了。

算法思想:

  • 按权值的递增次序选择合适的边来构造最小生成树
  • 每次选择一条权值最小的边,使这条边的两头连通(原本已经连通的就不选)直到所有节点都连通

算法演示:
在这里插入图片描述

3) 两个算法的比较

在这里插入图片描述

  • Prim算法的时间复杂度为O(|V|^2),不依赖于|E|
  • 在Kruskal算法中,采用堆来存放边的集合,因此每次选择最小权值的边只需O (log|E|) 的时间。由于生成树T中的所有边可视为一个等价类,因此每次添加新的边的过程类似于求解等价类的过程,由此可以采用并查集的数据结构来描述T,从而构造T的时间复杂度为O (|Elog|E|)

2. 最短路径

2.1 定义

在这里插入图片描述

2.2 分类

在这里插入图片描述

在这里插入图片描述

  • 单源最短路径:从源点到其余各顶点的最短路径
1)BFS求无权图的单源最短路径

在这里插入图片描述

在这里插入图片描述

缺点:BFS算法只适用于无权图,或所有边的权值都相同的图

2)Dijkstra算法求单源最短路径

算法思想:

  • 基于贪心策略
    在这里插入图片描述

算法时间复杂度:

  • 使用邻接矩阵表示时,时间复杂度为O (|V|^2)。
  • 使用带权的邻接表表示时,虽然修改dist[]的时间可以减少,但由于在dist[]中选择最小分量的时间不变,时间复杂度仍为O (|V|^2)

Prim算法和Dijkstra算法区别:

两者的区别在于,每次更新路径的不一样

  • prim更新的是已标记集合到未标记集合之间的距离
  • Dijkstra更新的是源点到未标记集合之间的距离

参考文献:
https://blog.csdn.net/dutmathjc/article/details/105888831
https://zhuanlan.zhihu.com/p/87748517

算法不足:

在这里插入图片描述

  • 其最短路径长度加上这条负边的权值结果可能小于原先确定的最短路径长度,而此时a在Dijkstra算法下是无法更新的
3)Floyd算法求各顶点之间最短路径

算法思想:
在这里插入图片描述

算法演示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

算法时间复杂度:
在这里插入图片描述

算法的缺点:

  • Floyd算法虽然用于负权值带权图,但不能解决负权回路图
    在这里插入图片描述

2.3 三种算法的比较

在这里插入图片描述

3. 有向无环图描述表达式

3.1 概述

在这里插入图片描述
有向无环图是描述含有公共子式的表达式的有效工具

在这里插入图片描述

  • 用二叉树来描述表达式时,有相同的子表达式
  • 利用有向无环图,则可实现对相同子式的共享,从而节省存储空间

3.2 DAG描述表达式

在这里插入图片描述

3.3 解题方法

在这里插入图片描述

4. 拓扑排序

4.1 AOV网

Activity on Vertex Network(AOV)网:一个有向图中,顶点表示活动,弧表示活动之间优先关系(不能存在回路)这样有向图为顶点表示活动的AOV网

在这里插入图片描述
特点:

  • 活动Vi是活动Vj的直接前驱,活动Vj是活动Vi的直接后继,这种前驱和后继关系具有传递性,且任何活动Vi不能以它自己作为自己的前驱或后继

4.2 拓扑排序概述

定义:

  • 对一个有向图构造拓扑序列的过程,即找一条从顶点Vi到Vj的一条路径且顶点序列中Vi必须在Vj之前

作用:

  • 解决一个工程能否顺利进行的问题

目的:

  • 找到做事的先后顺序

在这里插入图片描述

4.3 拓扑排序常用方法

在这里插入图片描述

在这里插入图片描述

4.4 拓扑排序复杂度

在这里插入图片描述
由于输出每个顶点的同时还要删除以它为起点的边

  • 故采用邻接表存储时拓扑排序的时间复杂度为O(|V|+|E|)
  • 采用邻接矩阵存储时拓扑排序的时间复杂度为O(|V|^2)

4.5 逆拓扑排序

在这里插入图片描述
特点:

  • 逆拓扑排序序列可能不唯一

5. 关键路径

5.1 AOE网

定义:
在这里插入图片描述
在这里插入图片描述

性质:
在这里插入图片描述

AOV网和AOE网的异同:

  • 同:都是有向无环图
  • 异:AOE网:边有权值;AOV网:边无权值,仅表示顶点之间前后关系

在这里插入图片描述
在这里插入图片描述

5.2 关键路径概述

  • 解决工程完成需要的最短时间问题,分析他们拓扑关系,找到当中最关键的流程,这个流程时间就是最短时间
  • 路径上各个活动持续的时间之后称为路径长度,从源点到终点具有最大长度的路径叫做关键路径,关键路径上的活动叫做关键活动

在这里插入图片描述
在这里插入图片描述

找关键活动时所需的参量:
在这里插入图片描述
ve(k) = e(i)

在这里插入图片描述
l(i) = vl(k)-weight

在这里插入图片描述

5.3 求关键路径的步骤

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

5.4 关键路径的特性

在这里插入图片描述
在这里插入图片描述


参考文献:王道数据结构

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——非线性结构(图) 的相关文章

随机推荐

  • socket局域网测试是可以的,但是在腾讯云/阿里云上报错“[Errno 99] Cannot assign requested address”

    现在云服务器一般都是只有内网地址 通过公网IP访问时 由云服务器运营商映射到内部网络的 因此 如果部署socket服务时 配置server ip应该是内网IP 解决方法 服务端的ip填服务器的私网ip 客户端填公网ip
  • 【Django】Python+Django 图文教程

    Django新手图文教程 本文面向 有python基础 刚接触web框架的初学者 环境 windows7 python3 5 1 pycharm专业版 Django 1 10版 pip3 一 Django简介 百度百科 开放源代码的Web应
  • 字节跳动测试岗面试挂在2面,复盘后,我总结了失败原因,决定再战一次...

    先说下我基本情况 本科不是计算机专业 现在是学通信 然后做图像处理 可能面试官看我不是科班出身没有问太多计算机相关的问题 因为第一次找工作 字节的游戏专场又是最早开始的 就投递了 投递的是游戏测试开发岗 字节是自己投的第一家公司 也是第一家
  • 【NLP】通过迁移学习加速 AI 模型训练

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Java机试题

    整理自Java经典编程50题 面试笔试机试 腾讯云开发者社区 腾讯云 1 回文数 public static boolean palindrom Integer integer String str1 String valueOf inte
  • Kibana在Centos上开机启动

    1 需要下载kibana 去官网下 2 解压到自己指定的目录下 我是放到了 usr local下 3 执行 vi usr lib systemd system kibana service 插入下面内容 Unit Description k
  • /dev/zero和/dev/null的区别

    可以通过使用dd if dev zero of archive test dbf bs 8k count 1000000 来测试磁盘的纯写入性能 使用dd if file of dev null 来测试磁盘的纯读取性能 使用dd if fi
  • 紫光同创 FPGA 开发跳坑指南(三)—— 联合 Modelsim 仿真

    Modelsim 是 FPGA 开发中重要的 EDA 设计仿真工具 主要用于验证数字电路设计是否正确 紫光 Pango Design Suite 开发套件支持联合 Modelsim 仿真 这里作简要的介绍 添加仿真库 方法一 打开 Pang
  • 实现mint操作(参考pancake)

    区块链发展越来越好 nft已经火了很久 今天写一下如何用js web3js 调用合约 实现mint nft 简单的调用 引入一些依赖 根据需要 有一些是其他功能的 import useActiveWeb3React from web3 ho
  • mysql read loop_mysql数据库游标的使用

    Mysql在5 0版本支持在存储过程中使用游标 游标声明必须出现在处理程序声明变量和条件的声明后 游标的使用如下 CREATE PROCEDURE curdemo BEGIN DECLARE done INT DEFAULT FALSE D
  • hive数据恢复

    truncate删除hive的表能恢复吗 0 jdbc hive2 localhost 10014 default gt create table test2 id int name string row format delimited
  • 在SpringBoot中利用nacos对数据源进行动态刷新

    一 重写DruidAbstractDataSource类 这里为什么要重写这个类 因为DruidDataSource数据源在初始化后 就不允许再重新设置数据库的url和userName 注意 类所在的包名必须为 com alibaba dr
  • MySQL 触发器

    文章目录 1 简介 2 行级与语句级触发器 3 触发时机 4 触发器优缺点 5 创建触发器 语法 示例 6 查看触发器 7 删除触发器 参考文献 1 简介 触发器 Trigger 是与表关联的命名数据库对象 当表发生特定事件时激活 触发器的
  • 概念解析

    注1 本文系 概念解析 系列之一 致力于简洁清晰地解释 辨析复杂而专业的概念 本次辨析的概念是 合成孔径雷达中运动补偿和自聚焦的联系与差别 概念解析 合成孔径雷达运动补偿与自聚焦的关系研究 基于二维空变运动补偿的机动平台大斜视SAR稀疏自聚
  • java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Date at org.hibernate.type.TimestampType.deepCopyNotNul

    在配置一对多的时候 OneToMany mappedBy recevier cascade CascadeType REMOVE OneToMany mappedBy sender cascade CascadeType REMOVE Ma
  • 日常学习--练手

    1 page source爬取页面源码 from selenium import webdriver import re driver webdriver Chrome driver get https www cnblogs com ca
  • mysql中如何取得分组中最大值的数据?全网最有效的方法

    大家都知道 MySQL有分组查询子句 group by 面试官就问你了 不是让你找到一个表中最大的值 而是让你找到最大值的整行数据 这个时候简单的分组是搞不定了 需要用到 inner join 子句 先说下inner join 子句的作用
  • 【MyBatis】Mybatis使用SqlSessionFactory加载xml文件

    1 概述 MyBatis框架主要是围绕着SqlSessionFactory这个类进行的 这个的创建过程如下 定义一个Configuration对象 其中包含数据源 事务 mapper文件资源以及影响数据库行为属性设置settings 通过配
  • python read函数返回值_python read()方法定义及使用(实例解析)

    今天这篇文章我们来了解一下pythonread方法 不知道没什么关系 因为今天讲的就是python之中的read 方法 以及知晓read是什么意思 所以今天我们在今天的文章之中来了解一下吧 概述 read 方法用于从文件读取指定的字节数 如
  • 数据结构——非线性结构(图)

    文章目录 一 非线性结构的概述 二 图的基本概念 1 定义 2 无向图 有向图 2 1 无向图 2 2 有向图 2 3 简单图 2 4 多重图 3 顶点的度 出度 入度 3 1 对于无向图 3 2 对于有向图 4 边的权 带权图 网 5 点