无向图邻接表实现

article/2025/8/27 21:41:42

无向图邻接表实现

顶点:按照编号顺序将顶点数据存储在一维数组当中

关联同一个顶点的边(以顶点为尾的弧):用线性链表存储

头结点:data+firstarc

表结点:adjvex(邻接点的序号,存放与vi邻接的顶点在表头数组中的位置)+nextarc(指向下一个边/弧的指针)
在这里插入图片描述

无向图的邻接表

特点:

  1. 邻接表不唯一

  2. 若无向图中有n个顶点、e条边,则其邻接表需要n个头结点和2e个表结点。适合存储稀疏图

    即空间复杂度为 O(n+2e)

  3. 有几个表结点就是有几个与其头结点相关联的边,也就是它的度是多少

  4. 无向图中顶点vi的度为第i个单链表中的结点数

有向图的邻接表

表结点:adjvex(头结点i为弧尾>的弧的结点)+nextarc(指向下一个边/弧的指针)

特点:

  1. 若有向图中有n个顶点、e条边,则其邻接表需要n个头结点和e个表结点,即空间复杂度为O(n+e)

  2. 顶点vi的出度为第i个单链表中的结点个数

  3. 顶点vi的入度为整个单链表中邻接点阈值是i-1的结点的个数

    找出度容易,找入度难

    使用逆邻接表:表结点:adjvex(头结点i为弧头的弧的结点)+nextarc(指向下一个边/弧的指针)

    这种邻接表找入度容易找出度难

当邻接表的存储结构形成后,图便唯一确定
在这里插入图片描述
AdjList[MVNum]是VNode结点构成的数组类型

即定义AdjList v相当于VNode v[MVNum]

边结点的定义:
在这里插入图片描述
图的结构的定义:
在这里插入图片描述
算法思想:

  1. 输入总顶点数和总边数
  2. 建立顶点表
    • 依次输入各个点的信息存入顶点表中
    • 使每个表头结点的指针域都初始化为NULL
  3. 创建邻接表
    • 依次输入每条边依附的两个顶点
    • 查找确定两个顶点的序号i和j,建立边结点
    • 将此边结点分别插入到vi和vj对应的两个边链表的头部,利用头插法,每次都插入在表结点的后面
      在这里插入图片描述
      在这里插入图片描述

代码实现创建邻接表

#include<iostream>
using namespace std;
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define MAXNum 100
//定义无穷大
#define  MAXInt 32767
typedef int Status;
//定义顶点数据类型
typedef char VerTexType;
//定义节点权重的类型
typedef int OtherInfo;
//定义边的数据类型
typedef struct ArcNode {int adjvex;//该边指向的顶点的位置ArcNode* nextarc;//指向下一条边的指针OtherInfo info;//与边相关的信息
}ArcNode;
//定义表结点的类型
typedef struct VNode {VerTexType data;//顶点信息ArcNode* firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MAXNum];//AdjList是邻接表类型
//图结构的类型
typedef struct {AdjList vertices;//邻接表int vexnum, arcnum;//图当前顶点数和弧数
}ALGraph;//图的定义
//该函数查找顶点x在图的顶点表中的下标
int LocateVex(ALGraph G, VerTexType x) {for (int i = 0; i < G.vexnum; i++) {if (G.vertices[i].data == x) {return i;}}return -1;
}//邻接表的创建——无向图
Status createUDN(ALGraph &G) {cout << "请输入无向图的总结点的数目和总的边数" << "\n";cin >> G.vexnum >> G.arcnum;cout << "请输入无向图中的各个顶点" << "\n";for (int i = 0; i < G.vexnum; i++){cin>>G.vertices[i].data;//初始化表头结点的指针域G.vertices[i].firstarc = NULL;}cout << "请输入每条边的信息:(顶点1 顶点2)" << "\n";for (int i = 0; i < G.arcnum; i++) {VerTexType x, y;cin >> x >> y;//查找两个顶点的下标int xIndex=LocateVex(G, x);int yIndex=LocateVex(G, y);//找到这两个顶点的下标之后就可以往firstarc域插入表结点了ArcNode* xArcNode = new ArcNode;ArcNode* yArcNode = new ArcNode;if (xIndex != -1 && yIndex != -1) {//在x结点后面插入邻接y结点的信息xArcNode->info = 1;xArcNode->adjvex = yIndex;xArcNode->nextarc = G.vertices[xIndex].firstarc;G.vertices[xIndex].firstarc = xArcNode;//在y结点后面插入邻接x结点的信息yArcNode->info = 1;yArcNode->adjvex = xIndex;yArcNode->nextarc = G.vertices[yIndex].firstarc;G.vertices[yIndex].firstarc = yArcNode;}else{return ERROR;}}return OK;
}void outPut(ALGraph G) {cout << "输出顶点表如下:" << "\n";for (int i = 0; i < G.vexnum; i++){cout << G.vertices[i].data << " ";}cout << "\n输入邻接表如下:" << "\n";for (int i = 0; i < G.vexnum; i++){printf("%c顶点相邻接的顶点为:\n", G.vertices[i].data);ArcNode* p=G.vertices[i].firstarc;while (p) {printf("%c ", G.vertices[p->adjvex].data);p = p->nextarc;}printf("\n");}}int main() {ALGraph G;createUDN(G);//输出该图进行查看,是否正确outPut(G);return 0;
}

测试样例:
在这里插入图片描述
在这里插入图片描述

邻接表示法的优缺点以及和邻接矩阵的关系

优缺点:

  1. 方便找任一顶点的所有“邻接点”
  2. 节约稀疏图的空间
    • 需要N个头指针和2E个结点(每个结点至少两个域)
  3. 方便计算任一顶点的“度”
    • 对无向图来说:是的
    • 对有向图:只能计算“出度”;需要构造逆邻接表(存指向自己的边)来方便计算“入度”
  4. 不方便检查任意一对顶点之间是否存在边

联系

  1. 邻接表中每个链表对应于邻接矩阵的一行,链表中结点个数等于一行中非零元素的个数

区别

  1. 对任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但是邻接表是不唯一的(链接次序与顶点编号无关)
  2. 邻接矩阵空间复杂度为O(n2),而邻接表的空间复杂度为O(n+e)
  3. 邻接矩阵多用于稠密图,而邻接表多用于稀疏图

http://chatgpt.dhexx.cn/article/wIGtQXsd.shtml

相关文章

邻接矩阵和邻接表

图的存储结构主要分两种&#xff0c;一种是邻接矩阵&#xff0c;一种是邻接表。 1.邻接矩阵 邻接矩阵的存储方式是用两个数组来表示图。一个一维数组储存图中顶点信息&#xff0c;一个二维数组储存图中的边或弧的信息。 无向图 这里右图是把顶点作为矩阵内行和列的标头罗列出…

图--邻接表

邻接表是图结构中的一种存储结构&#xff0c;适用于存储无向图和有向图。 邻接表存储图的实现方式是&#xff0c;给图中的各个顶点独自建立一个链表&#xff0c;用节点存储该顶点&#xff0c;用链表中其他节点存储各自的临界点。 与此同时&#xff0c;为了便于管理这些链表&a…

邻接表的实现(有向邻接表)、(无向邻接表),基于C++

邻接表 邻接矩阵的实现请看这里 是不错的一种图存储结构&#xff0c;但是&#xff0c;对于边数相对顶点较少的图&#xff0c;这种结构存在对存储空间的极大浪费。因此&#xff0c;找到一种数组与链表相结合的存储方法称为邻接表。 邻接表的处理方法是这样的&#xff1a; &a…

邻接表图文详解

在与链表相关的诸多结构中&#xff0c;邻接表是相当重要的一个。它是树与图结构的一般化存储方式&#xff0c; 邻接表可以看成“带有索引数组的多个数据链表”构成的结构集合。在这样的结构中存储的数据被分成若干类&#xff0c;每一类的数据构成一个链表。每一类还有一个代表元…

数据结构 图的邻接表

呃&#xff0c;下面该写邻接表了....... 邻接表的出现是因为图若是稀疏图&#xff0c;用邻接矩阵会造成空间的浪费&#xff0c;毕竟你要开辟一个一维数组和一个二维数组嘛&#xff0c;而且还是大开小用的那种。 邻接表为了避免内存的浪费引入了链式存储&#xff0c;它的处理办…

怎么画邻接表?不用邻接矩阵也能画?

目录 一、有向图的邻接表 二、无向图的邻接表 一、有向图的邻接表 最简单粗暴的方式就是把某个顶点发出的箭头指向的顶点全作为单个结点连接到此顶点的后面。结点数等于边数。 按正常思路的话&#xff0c;是一种递归遍历。 1.选一个点作为出发点。比如选一个v0。 2.从第一出…

数据结构之图(三)——邻接表

邻接表表示法(链式) 顶点&#xff1a; 按编号顺序将顶点数据存储在一维数组中。关联同一顶点的边&#xff1a; 用线性链表存储。如果有边\弧的信息&#xff0c;还可以在表结点中增加一项&#xff0c; 无向图的邻接表 例子&#xff1a; 特点&#xff1a; 邻接表不唯一若无向…

邻接表

邻接表&#xff1a;所谓邻接表&#xff08;adjacency list&#xff09;&#xff0c;就是把从同一个顶点发出的边链接在同一个称为边链表的单链表中。边链表的每个结点代表一条边&#xff0c;称为边结点。每个边结点有2 个域&#xff1a;该边终点的序号&#xff0c;以及指向下一…

图的邻接表

邻接表 图的邻接表存储方法跟树的孩子链表示法相类似&#xff0c;是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点&#xff0c;则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示&#xff0c;表结点存放的是邻接顶点在…

【数据结构】图的存储结构—邻接表

目录 什么是邻接表&#xff1f; 邻接表&#xff1a;定义 邻接表&#xff1a;相关类 邻接表&#xff1a;基本操作 1&#xff09;创建无向网 2&#xff09;创建有向网 3&#xff09;顶点定位 4&#xff09;插入边 5&#xff09;第一个邻接点 6&#xff09;查询下一个邻…

图的存储结构---邻接表

1. 邻接表&#xff08;无向图&#xff09; 对于边数相对顶点较少的图&#xff0c;可采取邻接表。把数组与链表结合在一起来存储&#xff0c;这种方式在图结构也适用&#xff0c;称为邻接表&#xff08;AdjacencyList&#xff09;。 2. 邻接表&#xff08;有向图&#xff09…

图的存储结构——邻接表

图的存储结构之邻接表 一、邻接表表示法无向图的邻接表有向图的邻接表有向图的逆邻接表 二、图的邻接表存储表示三、采用邻接表表示法创建无向网 一、邻接表表示法 回忆在线性表时&#xff0c;顺序存储结构就存在预先分配内存可能造成存储空间浪费的问题&#xff0c;于是引出了…

vivado实现FFT和IFFT信号处理

一&#xff0c;FFT的物理意义 FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的&#xff0c;但是如果变换到频域之后&#xff0c;就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外在频谱分析方面&a…

ifft java_OpenCV DFT_INVERSE与Matlab的ifft不同

我尝试使用opencv的dft函数过滤信号 . 我试图这样做的方式是在时域中获取信号&#xff1a; x [0.0201920000000000 -0.0514940000000000 0.0222140000000000 0.0142460000000000 -0.00313500000000000 0.00270600000000000 0.0111770000000000 0.0233470000000000 -0.00162700…

4.8 IFFT/FFT

4.8.1 IFFT/FFT原理 1. IFFT、FFT在OFDM系统中的应用 2、IFFT/FFT原理 3、DIT的基2FFT算法 4、DIF的基2FFT运算 5、基于的频率抽选FFT算法 4.8.2 基于 DIF FFT的硬件 结构 1、各级的蝶形运算硬件实现 2、transfer12、 transfer34、transfer56硬件实现 3、transfer23、 transfe…

Python实现FFT及IFFT

运行环境及编译工具 WindowsVS Code 编程语言及库版本 库版本Python3.7.0copy无numpy1.19.2opencv3.4.2PIL8.1.0matplotlib3.4.3 可执行文件 HW_2.pyHW_2.ipynb在HW_2.ipynb中执行&#xff0c;详细程序信息在HW_2.py中 问题 1 通过计算一维傅里叶变换实现图像二维快速傅里…

matlab FFT 和IFFT

代码&#xff1a; fs100;N128; n0:N-1;tn/fs; xsin(2*pi*40*t)sin(2*pi*15*t); subplot(221);plot(n,x,b); xlabel(时间/s);ylabel(x);title(原始信号); grid on;yfft(x,N); magabs(y); fn*fs/N; subplot(222);plot(f(1:N/2),mag(1:N/2)*2/N,b); xlabel(频率/Hz);ylabel(振幅)…

基于vivado实现FFT/IFFT

文章目录 前言一、基本过程二、vivado配置1.新建工程2.调用DDS的IP核2.调用FFT的IP核 三、编写Verilog程序1.顶层文件fft.v2.仿真文件fft_tb.v 四、运行仿真1. 运行仿真设置2. 仿真波形设置3. 结果分析 前言 使用vivado2018.3实现FFT&#xff0f;IFFT&#xff0c;过程比较详细…

python fft ifft

文章目录 条件代码实例 条件 任何一个满足狄利克雷条件的函数都可以通过傅里叶基数展开。 numpy和scipy中都有fft变换&#xff0c;且效果都是一样的。 代码 import numpy as np from scipy.fftpack import fft,ifft import matplotlib.pyplot as plt from matplotlib.pylab …

FFT专题:IFFT后信号如何重建

ifft(outFFTData, g_fft_temp, inFFTData, g_twiddle_ifft, twiddle_stride, F_WLEN);//思考ifft输出的复数结果怎么给到硬件输出 之前一直关注FFT后信号奔赴到频域处理,那么频域处理完后,怎么重建信号呢? 给出一段FFT和IFFT函数源码 int nFrameRunCount 0;#pragma section…