【数据结构】图的存储

news2025/4/9 11:48:21

目录

邻接矩阵

表示方法

代码定义

结构特点与度的信息

邻接表

表示方法

代码定义

结构特点与度的信息

十字链表

表示方法

第二步,将顶点x的firstIn域与所有headvex域为x的弧连起来。

结构特点与度的信息

邻接多重表

表示方法

结构特点与度的信息

图的存储方式辨析


邻接矩阵

表示方法

邻接矩阵是指通过一个一维数组来存放图里各个顶点的相关信息,再借助一个二维数组来存放图中边的信息,用于存储顶点邻接关系的二维数组被称作邻接矩阵。

邻接矩阵的命名规则如下:

对于无权图,若两点i,j有边相连,则A[i][j]=1;若没有边相连,则A[i][j]=0或无穷

对于有权图,若两点i,j有边相连,则A[i][j]=边的权重;若没有边相连,则A[i][j]=0或无穷

对于有向图,若有从i出发到j的箭头(i为弧尾,j为弧头),则A[i][j]=1或边的权重(无权或有权)。

给出三个例子,体会邻接矩阵:

例一:

其邻接矩阵为:

12345
101010
210100
301011
410100
500100

例二:

其邻接矩阵为:

1234
10110
20000
30001
41000

例三:

其邻接矩阵为:

12345
1020100
220700
307058
4100500
500800

代码定义

易知邻接矩阵的构成要素应该包括顶点表顶点数、边表边数,具体代码如下:

#define MaxVertexnum 100                 //最大顶点数
typedef char VertexType;                 //顶点数据类型
typedef int EdgeType;                    //边数据类型
typedef struct {                                    //邻接矩阵定义
    VextexType vex[MaxVertexnum];                   //顶点表
    EdgeType edge[MaxVertexnum][MaxVertexnum];      //边表
    int vexnum arcnum;                        //顶点数与边数
}MGraph;

结构特点与度的信息

邻接矩阵有下面几个特性:

1、无向图的邻接矩阵必为对称矩阵,所以存储时可以考虑压缩存储(【数据结构】矩阵与数组)。

2、有向图的邻接矩阵若为三角矩阵,则结构无环,一定可以进行拓扑排序(过两天出拓扑排序)。
3、邻接矩阵适合存储稠密图

那么从邻接矩阵中如何得到度的信息呢?

对于无权图,若为无向图的邻接矩阵,则顶点i的度为第i行所有元素的和;若为有向图的邻接矩阵,则\sum_{k}^{n}a_{i,k}(第i行所有元素的和)表示顶点i的出度,\sum_{k}^{n}a_{k,i}(第i列所有元素的和)表示顶点i的入度。


这里有一个小的知识点,对于无权图G邻接矩阵A的n次幂,有下面的结论:

A^{n}[i][j]表示路径长度为n的从i到j的路径条数。

如何证明?

考察矩阵的乘法,可知A^{2}[i][j]=\sum_{k}^{n}A[i][k]*A[k][j]。由于无权图的邻接矩阵只有0或1,所以对于求和符号里的单次相乘,如果i到k与k到j都有路径,则相乘得出的结果为1;若至少一条路径为0,则相乘结果为0;求和就是把所有的1加起来,即从i出发经过1-n所有顶点然后到j的路径条数。

考虑累乘的意义,n次幂代表着路径长度为n。(如果不清楚可以拿三次方自己手算一下,就很明了了)。


邻接表

表示方法

邻接表为图G中的每个顶点建立一个单链表,对于无向图,第i个单链表中的结点表示与顶点i相连的边;对于有向图,则表示以顶点i为起点的弧(即有向边)。每个顶点对应的单链表称为该顶点的边表(在有向图中称为出边表)。这些边表的头指针以及顶点的数据信息采用顺序存储的方式,共同构成顶点表。

因此,在邻接表结构中包含两种结点:顶点表结点和边表结点。

顶点表节点与边表节点结构示意如下所示:

对于下面的图,其邻接表示意如下:

例一:
 

例二:

代码定义

邻接表的代码结构包括了顶点表、边表和包含这两者以及其他信息的整个图结构,具体定义如下:

#define MaxVertexNum 100                //顶点数

typedef struct ANode{            //边表节点
    int adjvex;                  //这里因为顶点数据用数组存储,可以用数组下标int型表示而不用char
    struct ANode *nextarc;       //指针域
}ANode;

typedef struct VNode{         //顶点节点和顶点表
    char data;                    //顶点数据域
    ANode *firstarc;              //第一个指针
}VNode,AdList[MaxVertexNum];

typedef struct{
    AdList vertices;            //顶点表
    int vexnum, arcnum;         //边点数量
}ALGraph;

结构特点与度的信息

邻接表的结构特点如下:

1、无向图的边表结点数是总结点数的两倍,有向图的边表结点数与总结点数相等。无向图邻接表存储空间为O(\left | V \right |+2\left | E \right |),有向图邻接表存储空间为O(\left | V \right |+\left | E \right |)。

2、邻接表不唯一,因为边表结点链表的次序可以改变。

3、邻接表适合存储稀疏图

邻接表隐含的度的信息如下:

1、无向图顶点表某个顶点连着的边表结点个数就是该顶点的度。

2、有向图定顶点的出度等于该顶点连着的边表结点个数,入度需要遍历整个邻接表进行统计。

十字链表

表示方法

十字链表用于表示有向图。十字链表有两种结点结构,一种为顶点结点,一种为弧结点。

顶点结点包含三个域:数据域data、第一个入度域firstin(以该点为弧头的第一个弧)和第一个出度域firstout(以该点为弧尾的第一个弧)。

弧结点包含五个域:弧尾数据域tailvex、弧头数据域headvex、相同弧头指针域hlink(即与该弧同弧头的下一个弧)、相同弧尾指针域tlink(即与该弧同弧尾的下一个弧)和权值域info。

结构示意图如下:

这里注意不要轻易改变域的顺序,就按照上图原封不动地抄下来。

那么为什么要这样设定呢?现在给出一个无权图(无info域)的十字链表构建过程就能很清晰地知道了。

第一步,列出顶点表,并将所有以该顶点为弧尾(从该点出发)的弧列在该顶点的同一行,并且把同一行的弧都连起来。

第二步,将顶点x的firstIn域与所有headvex域为x的弧连起来。

那么一个图的十字链表就画完了。

结构特点与度的信息

从上面的绘图过程可以看出,十字链表表示的图很轻松就能够找到一个顶点的入度、出度或者一个弧相邻的两个点。同时,删除一个节点、一个弧的时间复杂度也是很低的。

需要注意的是,十字链表不唯一,但十字链表唯一确定一个图。

邻接多重表

表示方法

与十字链表相对应,无向图可以用类似的方法表示。但是由于无向图边的无向性,我们不用区分头和尾。

邻接多重表链表有两种结点结构,一种为顶点结点,一种为弧结点。

顶点结点包含两个域:数据域data、第一条边域firsedge。

弧结点包含五个域:i顶点数据域ivex、i顶点相邻边指针域ilink、j顶点数据域jvex、j顶点相邻边指针域jlink和权值域info。

这里同样给一个无向无权图的构建过程。

第一步,列出顶点表与所有边。 

第二步,哪里有空插哪里。 

结构特点与度的信息

相似地,邻接多重表表示的图很轻松就能够找到一个顶点的度或者一个边相邻的两个点。同时,删除一个节点、一个弧的时间复杂度也是很低的。

图的存储方式辨析

邻接矩阵邻接表十字链表邻接多重表
空间复杂度O(\left | V^{2} \right |)O(\left | V \right |+\left | E \right |)O(\left | V \right |+2\left | E \right |)O(\left | V \right |+\left | E \right |)O(\left | V \right |+\left | E \right |)
找邻边时间复杂度O(V)有向图的入度要遍历整个表,别的挺方便方便方便
删除边或者顶点删边容易删点难有向:删边容易删点难;无向:都难方便方便
适用于稠密稀疏只能有向只能无向
表示方式唯一不唯一不唯一不唯一

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何解决uniapp打包安卓只出现功能栏而无数据的问题

如何解决uniapp打包安卓只出现功能栏而无数据的问题 经验来自:关于Vue3中调试APP触发异常:exception:white screen cause create instanceContext failed,check js stack -> at useStore (app-service.js:2309:15)解决方案 - 甲辰哥来帮你算命 - 博客…

kotlin,数字滚动选择

用国内的通义灵码和codegeex都没有弄出来,最后只得用墙外的chatgpt才弄出一个满意的。kotlin真的有点难,好在有AI,让学习没这难了。 package com.example.mynumsetimport android.os.Bundle import androidx.activity.ComponentActivity imp…

【4】搭建k8s集群系列(二进制部署)之安装master节点组件(kube-apiserver)

一、下载k8s二进制文件 下载地址: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG -1.20.md 注:打开链接你会发现里面有很多包,下载一个 server 包就够了,包含了 Master 和 Worker Node 二进制文件。…

每日c/c++题 备战蓝桥杯(小球反弹)[镜像思路求解,最小公倍数]

思路: 错解:对于这道题而言,有的同学会选择用计算每次碰撞的坐标,直到坐标等于原点的方法来做,但这种方法实现起来比较繁琐,并且由于碰撞点的坐标有可能是浮点数,而浮点数会丢失精度&#xff0…

新潮透明液体水珠水滴失真故障扭曲折射特效海报字体标题设计ps样机动作素材 Bubble Photoshop Templates

只需单击几下即可创建引人注目的视觉效果!您需要做的就是将您的文本或图像放入智能对象中并应用作。 包中包含: 15 个静态 Photoshop 模板(PS 2019 及更高版本) 01-05 垂直布局 (22504000)06-10 水平布局…

从零开始玩python--python版植物大战僵尸来袭

大家好呀,小伙伴们!今天要给大家介绍一个超有趣的Python项目 - 用pygame制作植物大战僵尸游戏的进阶版本。相信不少小伙伴都玩过这款经典游戏,今天我们就用Python来实现它,让编程学习变得更加有趣!🌟 一、…

Visual Studio Code SSH 连接超时对策( keep SSH alive)

文章目录 问题解决方法一&#xff1a;配置服务端关于ClientAliveInterval和ClientAliveCountMax1、打开终端&#xff0c;打开SSH配置文件&#xff1a;输入以下命令&#xff1a;2、打开配置文件后&#xff0c;添加以下内容&#xff1a;3、添加后&#xff0c;Esc按 <Enter>…

【C语言入门】由浅入深学习指针 【第二期】

目录 1. 指针变量为什么要有类型&#xff1f; 2. 野指针 2.1 未初始化导致的野指针 2.2 指针越界导致的野指针 2.3 如何规避野指针 3. 指针运算 3.1 指针加减整数 3.2 指针减指针 3.3 指针的关系运算 4. 二级指针 5. 指针数组 5.1 如何使用指针数组模拟二维数组 上…

关于Ubuntu系统的远程控制及文件传输

目录 1. 网络配置1.1 虚拟机Ubuntu网络配置1.2树莓派网络配置 2. 远程终端登录3. FTP文件传输4. 安装Xming和PuTTY5. 使用X11转发6. 安装和使用VNC思考题解答参考资料 1. 网络配置 1.1 虚拟机Ubuntu网络配置 将虚拟机的网络连接设置为“桥接模式”&#xff0c;这样虚拟机的网…

IS-IS-单区域的配置

一、IS-IS的概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种‌链路状态路由协议‌&#xff0c;最初设计用于‌OSI&#xff08;Open Systems Interconnection&#xff09;参考模型‌的网络层&#xff08;CL…

Flask使用MySQL数据库通过Flask-SQLAlchemy 迁移数据库,实际更新文件,但是提示没有检测到数据更新。

本地写了一个model的用户类&#xff0c;数据库连接信息正确&#xff0c;执行下面2条命令进行数据库迁移。 flask db migrate 生成迁移文件 flask db upgrade 执行迁移文件的升级 发现执行完后&#xff1a;提示没有检测到数据的更新 PS C:\Users\mu> flask db migrate IN…

USB3.0走线注意事项和其中的协议

USB3.0走线的要求&#xff1a; 1、USB要走差分&#xff0c;阻抗控制为90欧姆&#xff0c;并包地处理&#xff0c;总长度最好不要超过1800mil. 2、尽可能缩短走线长度&#xff0c;优先考虑对高速USB差分&#xff08;RX、TX差分&#xff09;的布线&#xff0c;USB差分走线在走线…

QML 菜单控件:MenuBar、MenuBarItem、Menu、MenuItem层级关系和用法

目录 引言相关阅读关于MenuBarItem核心代码1. 主菜单栏 (MenuBar.qml)2. 主页面&#xff0c;包含右键菜单 (MainPage.qml)3. 主界面绑定 (Main.qml)整体结构 运行效果总结工程下载 引言 在 GUI 开发中&#xff0c;菜单是用户交互的核心组件。QML 提供了一套灵活的菜单控件&…

蓝桥杯嵌入式第十四届模拟二

一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.c、fun.h、headfile.h文件,去资源包中把lc…

Qt 入门 1 之第一个程序 Hello World

Qt 入门1之第一个程序 Hello World 直接上操作步骤从头开始认识&#xff0c;打开Qt Creator&#xff0c;创建一个新项目&#xff0c;并依次执行以下操作 在Qt Creator中&#xff0c;一个Kits 表示一个完整的构建环境&#xff0c;包括编译器、Qt版本、调试器等。在上图中可以直…

架构思维: 全链路日志深度解析

文章目录 引言&#xff1a;微服务时代的日志挑战一、业务痛点与需求分析二、技术选型的六维评估模型1. 标准化支持 OpenTracing2. 存储扩展性3. 性能损耗4. 功能完备性5. 侵入性控制6. 社区生态 三、SkyWalking落地实践与调优1. 核心架构解析2. 关键配置示例&#xff1a; 采样率…

唯美社区源码AM社区同款源码

源码介绍 唯美社区源码AM社区同款源码 后端修改application.properties文件内容为你的数据库 前端修改/config/config.js文件内容为你的后端地址 这两个文件里要修改的地方我已经用中文标注出来了 截图 源码免费下载 唯美社区源码AM社区同款源码

3. go-zero中如何使用redis

问题 go-zero项目相关文档中redis是这样配置的&#xff1a; Name: account.rpc ListenOn: 0.0.0.0:8080 Etcd:Hosts:- 127.0.0.1:2379Key: account.rpcMysql:Host: xxxx:3306User: rootPass: xxxData: mall-userCharset: utf8mb4Cache: - Host: 192.168.145.10:6379Type: nod…

cpp自学 day19(多态)

一、基本概念 同一操作作用于不同的对象&#xff0c;产生不同的执行结果 &#x1f449; 就像「按F1键」&#xff1a;在Word弹出帮助文档&#xff0c;在PS弹出画笔设置&#xff0c;​同一个按键触发不同功能 &#xff08;1&#xff09;多态类型 类型实现方式绑定时机​静态多态…

【算法/c++】利用中序遍历和后序遍历建二叉树

目录 题目&#xff1a;树的遍历前言题目来源树的数组存储基本思想存储规则示例 建树算法关键思路代码总代码 链表法 题目&#xff1a;树的遍历 前言 如果不是完全二叉树&#xff0c;使用数组模拟树&#xff0c;会很浪费空间。 题目来源 本题来自 PTA 天梯赛。 题目链接: 树…