图论之邻接表

2023-05-16

 路径规划系列文章目录

  1. 路径规划算法综述
  2. 图论基础介绍
  3. 图论之邻接矩阵

目录

 路径规划系列文章目录

一、邻接表

二、邻接表实现

2.1 链式前向星实现

2.2 链表实现

三、总结


一、邻接表

        由于对于稀疏图来说,使用邻接矩阵进行存储显然会使得空间利用率较低,因此利用邻接表来存储图,可以克服这一缺点。

        前面我们提到过,图其实就是由顶点和边构成的,因此我们可以将图分两部分来组织,即顶点与其连接的边。对于顶点而言,我们只需要存储顶点的信息以及边的地址,存储顶点信息代表着顶点的编号,有了边的地址就能够访问与其相连的边的信息,此外一般我们将顶点按照1,2,3...n来进行编号,这样可以将顶点表示为一个数组,只需要通过顶点编号对应位下标即可访问各个顶点。对于边来说,只需要存储边的权重,所连接的顶点编号以及下一条边的地址即可,因此边适合用链表来存储。

        综上所述的分析,我们可以知道顶点表的要点主要有:

  1. 顶点表是一个数组,每个结点通过结点编号所对应的下标访问
  2. 结点中包含存储的顶点数据,这里是顶点编号
  3. 每个顶点表的结点中还包含其所对应边结点的地址,由于边是用链表来表示的,因此只需要知道与其相连的任意一条边结点的地址即可。

        因此顶点表的结点如下图所示。

        同样地,边链表的要点有:

  1.  边链表是链表构建成的
  2. 边链表中包含该边的权重
  3. 边链表中还包含另一个顶点信息,(由于边链表一定是根据某个顶点访问到的,因此在访问边链表前已经知道了一个顶点的信息,所以只需要在记录下另一个顶点的信息即可)
  4. 边链表中包含连接在该顶点上的下一条边的地址(以便访问下一条边)

        因此边链表的结点如下图所示。

 下面是一张图与其对应邻接表的示例:
 

二、邻接表实现

        这里提供两种邻接表的实现方法,一种是链式前向星的方法,另一种是使用链表实现。下面分别介绍。

2.1 链式前向星实现

        使用链式前向星其实就是利用两个数组来模拟链表实现邻接表,并且我们不但对顶点进行编号,我们还对边进行编号,因为每一条边都包含信息,相对于其他边都是独立的,因此我们可以将边也用数组来表示,并且使用其下标访问。

        我们重点来介绍如何添加边的信息。我们使用head[]数组来表示头结点,如head[n] = a;表示头结点n的首个边的编号为a。用e[]结构体数组表示边结点。边界点存储了该边的权重、下一个结点的编号,以及下一条边的编号。其定义如下

const int M=500;//边的最大数量 
struct Edge //边结结点构体 
{
	int to,w;//分别表示下一个顶点编号以及该条边的权重	
	int next;//下一条边的编号 
}e[M]; 

        我们从1开始对边结点进行编号,每添加一条边,编号就+1,添加时采用头插法添加,比如说当向第i个顶点上添加边的时候,只需要将新的边的next=head[i],然后将head[i]=新的边的编号即可。这里使用一个整型变量idx为其分配编号。

         插入结束后,则链表状态如下所示

        代码如下所示

#include<iostream>
#include<cstring>
using namespace std;

const int N=500;//顶点最大数量 
const int M=500;//边的最大数量 
const int INF = 1e9;//最大权重 

int n;
int head[N];//顶点结点数组 
int idx;//边结点的编号 


struct Edge //边结结点构体 
{
	int to,w;//分别表示下一个顶点编号以及该条边的权重	
	int next;//下一条边的编号 
}e[M]; 

void init()
{
	memset(head,-1,sizeof(head));//将头结点指向第一个编号设置为-1 
	idx = 1;//边编号从1开始 
}

void add(int a,int b,int w)//添加边 
{
	e[idx].to = b;//与边相连的另一个顶点编号 
	e[idx].w = w;//设置权重 
	e[idx].next = head[a];//边指向顶点a的下一条边的编号 
	head[a] = idx;//更新顶点a指向的边 
	idx++;//编号自增1 
}

void testEdge()
{
	int m;
	cin>>n>>m;//输入顶点数量和边的数量 
	init();
	int a,b,w;
	while(m--)
	{
		cin>>a>>b>>w;
		add(a,b,w);	
	}
	
	/*按照结点打印图*/ 
	for(int i=1;i<=n;i++)
	{
		cout<<i<<"->";
		for(int j=head[i];j!=-1;j=e[j].next)
		{
			cout<<e[j].to<<"("<<e[j].w<<")"<<"->"; 
		}
		cout<<endl;
	}
	
}

int main()
{
	testEdge();
}

2.2 链表实现

#include<iostream>
#include<queue>
#include<stack>

using namespace std;

#define INF 65333
#define MaxVerNum 1000 //定义最大顶点个数
typedef char elementType; //定义定点数据类型
typedef int einfoType;  //定义权值数据类型 
 
//边链表结点结构 
typedef struct eNode
{
	int adjVer; //边链表编号
	einfoType einfo;//边链表边信息
	struct eNode* next; //边链表下一个结点 
}EdgeNode;//链表结点类型 

typedef struct vNode
{
	elementType data;//存放图中顶点数据值 
	EdgeNode* firstEdge;
}VerNode;//顶点表结点类型 


class Graph
{
private:
	VerNode* VerList;//结点 
	int VerNum;//顶点个数 
	int ArcNum;//边数 

public:

	void CreateGraph();
	void printGraph();
};

void Graph::CreateGraph()
{
	int vNum,aNum;
	cin>>vNum>>aNum;//输入顶点数量和边数量 
	ArcNum = aNum;
	VerNum = vNum; 
	VerList = new VerNode[VerNum+1];//给顶点表开辟空间 
	
	while(vNum)//初始化顶点表 
	{
		VerList[vNum].data = 0;
		VerList[vNum].firstEdge = NULL;
		vNum--;
	}
	
	aNum = ArcNum;
	
	while(aNum--)//输入图信息 
	{
		int a,e,w;
		cin>>a>>e>>w;
		EdgeNode *en = new EdgeNode; 
		en->einfo = w;//给边付权重 
		en->adjVer = e;//设置另一个顶点编号 
		VerList[a].data = a;//设置该顶点编号 
		en->next = VerList[a].firstEdge;//该边结点下一个指向第一个边结点 
		VerList[a].firstEdge = en;//第一个边结点指向该边 
	}

}

void Graph::printGraph() 
{
	int vNum;
	vNum = VerNum;
	while(vNum)
	{
		EdgeNode* pe;
		cout<<vNum<<"->";
		for(pe = VerList[vNum].firstEdge;pe!=NULL;pe=pe->next)
		{
			cout<<pe->adjVer<<"("<<pe->einfo<<")->";
		}
		vNum--;
		cout<<endl;
	}
}

int main()
{
	Graph g;
	g.CreateGraph();
	g.printGraph();
}

三、总结

        本文介绍了图的邻接表存储方法,使用邻接表存储图要稍微复杂一些,但能够提高空间利用率。本文给出了两种实现方法,一种是链式前向星,另一种是链表实现,链式前向星是利用数组来模拟链表,并且在最后给出了邻接表的一种打印方法。

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

图论之邻接表 的相关文章

  • 【2018.04.19 ROS机器人操作系统】机器人控制:运动规划、路径规划及轨迹规划简介之一...

    参考资料及致谢 本文的绝大部分内容转载自以下几篇文章 xff0c 首先向原作者致谢 xff0c 希望自己能在这些前辈们的基础上能有所总结提升 1 运动规划 路径规划 轨迹规划的联系与区别 https blog csdn net wx5456
  • "symbol lookup error"问题解决

    http www linuxquestions org questions slackware 14 symbol lookup error usr lib libgtk x11 2 0 so 0 undefined symbol 4343
  • 如何自定义一个通信协议

    借鉴简单的OSI和TCP IP通信模型来讨论如何自定义一个适应自己的通信协议 文章目录 64 toc 1 前言2 经典的OSI七层模型2 1 TCP IP模型解析2 1 1 整体介绍2 2 2 数据链路层2 2 3 网络层2 2 4 传输层
  • 程序员每天工作多少个小时_程序员每天实际工作几个小时?

    程序员每天工作多少个小时 您如何看待 xff0c 程序员每天实际工作多长时间 xff1f 大多数人会说答案是8到9个小时 有人说他们每天工作12个小时或更长时间 尽管这是正确的 xff0c 但它并不是大多数程序员实际工作的数量 xff0c
  • 九轴姿态传感器的介绍和应用

    总体设计 姿态传感器是基于MEMS技术的高性能三维运动姿态测量系统 它包含三轴陀螺仪 三轴加速度计 xff0c 三轴电子罗盘等运动传感器 xff0c 通过内嵌的低功耗ARM处理器得到经过温度补偿的三维姿态与方位等数据 利用基于四元数的三维算
  • CAN总线简单介绍

    什么是CAN总线 xff1f Controller Area Network xff0c 简称CAN或者CAN bus 是一种功能丰富的串行总线标准 xff0c 最早的CAN控制芯片在奔驰车上应用并量产 xff0c 因为支持多主机 xff0
  • Ubuntu18.04 下realsense编译与安装

    相机型号 xff1a realsense SR300 系统环境 xff1a Ubuntu18 04 我这里是下载并编译源码的方式进行编译安装 具体编译安装可以参照https github com IntelRealSense libreal
  • Linux gvim 编辑器修改配色方案、字体、字号

    1 gvim相比于vim xff0c 目前知道gvim是可以单独窗口运行的 xff0c 像gedit一样 vim打开的文件貌似只能显示在终端内 但是二者安装的位置以及配置文件是很有联系的 xff0c 暂时的感觉是gvim是对vim的封装 x
  • 【路径规划】(3) RRT 算法求解最短路,附python完整代码

    大家好 xff0c 今天和各位分享一下机器人路径规划中的 RRT 算法 xff0c 感兴趣的点个关注 xff0c 文末有 python 代码 xff0c 那我们开始吧 1 算法介绍 RRT 算法是由学者 S M LaValle 提出来的路径
  • 【自动化测试】【安卓android】python 发送adb命令方法

    command 命令列表 xff0c 可以传入任意命令 xff0c 类型为list cmdMode可以选择发送命令方式为直接发送adb 命令还是先进入shell def sendAdbcmd command deviceID 61 34 3
  • 选择恐惧症的福音!教你认清MVC,MVP和MVVM

    相信大家对MVC xff0c MVP和MVVM都不陌生 xff0c 作为三个最耳熟能详的Android框架 xff0c 它们的应用可以是非常广泛的 xff0c 但是对于一些新手来说 xff0c 可能对于区分它们三个都有困难 xff0c 更别
  • FreeRtos嵌入式操作系统学习1--操作系统原理初探

    这里由于是第一篇文章 xff0c 不讲复杂的数据机构 xff0c 也不进行代码分析 xff0c 只讲嵌入式操作系统原理 先看下面一个简单的程序 xff1a void task1 while 1 Led1 1 xff08 1 xff09 de
  • 初学四旋翼之定高

    本项目使用US 100超声波模块测高 xff0c 与飞控的通讯方式为UART 硬件连接应注意 xff1a 通常飞控的发送管脚连超声波的接收管脚 xff0c 飞控的接收管脚连超声波的发送管脚 xff08 即tx rx xff1b rx tx
  • 初学四旋翼之光流定点

    本项目使用px4flow模块测速 xff0c 与飞控的通讯方式为I2C 安装时因注意光流模块与飞控的方向 xff08 一 xff09 为什么使用光流模块 xff1f 在悬停时 xff0c 若采用开环控制 xff0c 由于一些不可控的外界因素
  • 初学JetsonTX2之部署YOLO

    本人准备使用 YOLO进行人脸检测 xff0c 硬件设备为 Jetson TX2 查阅 YOLO 官网 xff0c 要部署 YOLO xff0c 首先要安装 CUDA CUDNN OPENCV xff0c 然后部署 Darknet xff0
  • C语言,超过10位数的字符串转整型函数

    include lt stdio h gt static long str2int const char str long temp 61 0 const char p 61 str if str 61 61 NULL return 0 i
  • C语言去掉MAC地址中的冒号

    include lt stdio h gt include lt string h gt void strdel char s char del x char p char q for p 61 s q 61 s p 61 39 0 39
  • Jetson Xavier NX 套件将系统装到SSD

    目录 第一步 xff1a 虚拟机 第二步 xff1a 装SDK Manager 第三步 xff1a 将系统装到eMMC 第四步 xff1a 将系统装到SSD内 xff0c 我以新买的500G硬盘为例 第五步 xff1a 装各种库 解决问题时
  • MySQL使用.ibd文件恢复或者迁移数据库

    使用86的Alice数据库的 ibd文件备份 恢复到76数据库 xff0c 该数据库版本为8 0 17 1 创建一个表确认与原始表结构一致 将86数据库的表结构导出 xff0c 在76上执行 xff08 注 xff1a 在5 5 26版本需
  • 学习ARM反汇编工具objdump和一个简单实例

    学习ARM反汇编工具objdump和一个简单实例 参考朱有鹏ARM裸机编程 1 反汇编的原理 amp 为什么需要反汇编 arm linux objdump D led elf gt led elf dis objdump是gcc工具链中的反

随机推荐

  • 从零开始学习UCOSII操作系统1--UCOSII的基础知识

    从零开始学习UCOSII操作系统1 UCOSII的基础知识 前言 xff1a 首先比较主流的操作系统有UCOSII FREERTOS LINUX等 xff0c UCOSII的资料相对比其余的两个操作系统的资料是多很多的 更重要的原因是自己本
  • 从零开始学习UCOSII操作系统2--UCOSII的内核实现

    从零开始学习UCOSII操作系统2 UCOSII的内核实现 参考书籍 xff1a 嵌入式实时操作系统 COS II原理及应用 嵌入式实时操作系统uCOS II 邵贝贝 第二版 1 任务的结构 任务控制块 首先这个任务控制块是非常的大的 xf
  • 从零开始学习UCOSII操作系统4--任务管理

    从零开始学习UCOSII操作系统4 任务管理 1 重讲任务 1 任务可以是一个无限的循环 xff0c 也可以在一次执行完毕后被删除 这里需要注意的是 xff0c 任务的代码并不是真正的删除了 xff0c 而是UCOSII不再理会该任务代码
  • 从零开始学习UCOSII操作系统7--信号量

    从零开始学习UCOSII操作系统7 信号量 参考博客 xff1a 64 http blog csdn net gatiemehttps blog csdn net gatieme article details 21071379 前言 xf
  • 从零开始学习UCOSII操作系统15--总结篇

    从零开始学习UCOSII操作系统15 总结篇 前言 xff1a 在大学的时候 xff0c 我们班级上面都有很多人觉得学习UCOSII 包括UCOSIII 是没什么厉害的 xff0c 因为很多人都喜欢去学习Linux操作系统 xff0c 但是
  • 手把手教你搭建TFTP服务器

    手把手教你搭建TFTP服务器 前言 xff0c 东西来自于网络 xff0c 但是根据自己的理解写了一下建议 xff0c 记录下来 xff0c 让下次不要在网络上面浪费时间搜索 1 保证自己的虚拟机能够上网 测试方法 xff1a 里面一般都有
  • 从零开始写一个单向不循环链表

    从零开始写一个单向不循环链表 总结 xff1a 郝斌数据结构与算法课程 数据结构概述 xff1a 定义 xff1a 我们如何把现实中大量的而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器 xff08 内存 xff09 中 xff0
  • STM32-CAN通信协议

    STM32 CAN通讯协议 CAN协议简述 CAN Controller Area Network xff08 控制器局域网 xff09 xff0c 由Bosch开发的一种面向汽车的通信协议 这是目前应用最广泛的通信协议 xff0c 更是尤
  • FreeRTOS-任务运行时间统计

    FreeRTOS 任务运行时间统计 引入 上一章节中我们讲述了任务信息获取 xff0c 我们已经能够获取绝大部分任务信息了 xff0c 但是任务还有一个很重要的信息 xff0c 那就是运行时间 如果我们知道了每个任务的运行时间和占比我们就可
  • 【Linux】解决Nvidia Jetson Xavier NX开发套件开机启动时间过长问题

    环境 硬件 xff1a Jetson Xavier NX 套件 系统 xff1a Ubuntu 20 04 解决 0 现象 在使用Nvidia 的Jetson Xavier NX套件 xff0c 开发产品 xff0c 准备发布时 xff0c
  • FreeRTOS-信号量

    FreeRTOS 信号量 信号量其实就是队列的一种应用 xff0c 信号量的各种操作都是在队列的基础上建立起来的 那么既然是在队列的基础上建立的 xff0c 信号量一定具有和队列相同的属性 因此信号量也是为任务和任务 任务和中断之间通信做准
  • FreeRTOS-空闲任务及钩子函数

    FreeRTOS 空闲任务及钩子函数 FreeRTOS中空闲任务是开启任务调度器自动创建的一个任务 xff0c 这样可以保证系统中有任务可以运行 xff0c 这个任务优先级是最低的 xff0c 如果有其他任务处于就绪态 xff0c 那么空闲
  • FreeRTOS-内存管理-完结篇

    FreeRTOS 内存管理 无论是创建任务 队列 信号量还是其他的东西 xff0c 都需要为其分配一定空间 xff0c 前面我们都是运用动态内存申请的方法来申请空间 xff0c 并且我们所使用的的动态内存申请函数都是FreeRTOS自己提供
  • OpenCV环境搭建

    OpenCV环境搭建 VS2017安装 具体安装过程参考下面链接 xff1a https mp weixin qq com s NrrHFAXm57QblOf5CPUVmw 组件可以参考以下选项 xff1a OpenCV安装 如果还没有安装
  • W2-图像增强

    线性变换 imag span class token operator 61 span span class token function imread span span class token punctuation span span
  • 半天光速入门Python(上)

    文章目录 写在前面一 Python环境Python解释器与编辑器WinDows用户Linux用户 二 基础概念 运算符与表达式常量数类型字符串变量与标识符对象逻辑行与物理行缩进运算符注释方法与C语言区别 三 三种程序结构ifforwhile
  • 路径规划算法综述

    路径规划算法综述 路径规划算法综述 文章目录 路径规划算法综述路径规划算法主要问题一 主要问题及现有解决方案1 环境建模问题2 收敛速度和局部最优解 二 路径规划算法分类及简介2 1传统算法2 1 1全局路径规划算法2 1 1 1 A 算法
  • 图论基础介绍

    路径规划系列文章目录 路径规划算法综述 文章目录 路径规划系列文章目录图论基础介绍一 图的基本概念1 1 图的定义1 2 图的分类1 2 1 无向图1 2 2 有向图1 2 3 带权图 二 图的相关术语2 1 邻接 adjacent 2 2
  • 图论之邻接矩阵

    路径规划系列文章目录 路径规划算法综述图论基础介绍 目录 路径规划系列文章目录 一 图的存储方式介绍 二 邻接矩阵介绍 三 邻接矩阵实现 四 总结 一 图的存储方式介绍 图的结构比较复杂 xff0c 是非线性结构 xff0c 任意两点都可能
  • 图论之邻接表

    路径规划系列文章目录 路径规划算法综述图论基础介绍图论之邻接矩阵 目录 路径规划系列文章目录 一 邻接表 二 邻接表实现 2 1 链式前向星实现 2 2 链表实现 三 总结 一 邻接表 由于对于稀疏图来说 xff0c 使用邻接矩阵进行存储显