图的邻接表

article/2025/8/27 22:33:08

邻接表

图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。 [1] 

邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。

在有向图中,描述每个点向别的节点连的边(点a->点b这种情况)。

在无向图中,描述每个点所有的边(点a-点b这种情况)

与邻接表相对应的存图方式叫做边集表,这种方法用一个容器存储所有的边。

 

 

 

总代码

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h> 
#define QUEUE_SIZE 10int* visitedPtr;typedef struct Graph{int** connections;int numNodes;
} *GraphPtr;//初始化 
GraphPtr initGraph(int paraSize, int** paraData) {int i, j;GraphPtr resultPtr = (GraphPtr)malloc(sizeof(struct Graph));resultPtr -> numNodes = paraSize;//resultPtr -> connections = (int**)malloc(paraSize * paraSize * sizeof(int));resultPtr -> connections = (int**)malloc(paraSize * sizeof(int*));for (i = 0; i < paraSize; i ++) {resultPtr -> connections[i] = (int*)malloc(paraSize * sizeof(int));for (j = 0; j < paraSize; j ++) {resultPtr -> connections[i][j] = paraData[i][j];}//Of for j}//Of for ireturn resultPtr;
}//Of initGraph//创建队列 
typedef struct GraphNodeQueue{int* nodes;int front;int rear;
}GraphNodeQueue, *QueuePtr;//初始化队列 
QueuePtr initQueue(){QueuePtr resultQueuePtr = (QueuePtr)malloc(sizeof(struct GraphNodeQueue));resultQueuePtr->nodes = (int*)malloc(QUEUE_SIZE * sizeof(int));resultQueuePtr->front = 0;resultQueuePtr->rear = 1;return resultQueuePtr;
}//Of initQueue//判断队列是否为空 
bool isQueueEmpty(QueuePtr paraQueuePtr){if ((paraQueuePtr->front + 1) % QUEUE_SIZE == paraQueuePtr->rear) {return true;}return false;
}//Of isQueueEmpty//入队 
void enqueue(QueuePtr paraQueuePtr, int paraNode){if ((paraQueuePtr->rear + 1) % QUEUE_SIZE == paraQueuePtr->front % QUEUE_SIZE) {printf("Error, trying to enqueue %d. queue full.\r\n", paraNode);return;}//Of ifparaQueuePtr->nodes[paraQueuePtr->rear] = paraNode;paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE;
}//Of enqueue//出队 
int dequeue(QueuePtr paraQueuePtr){if (isQueueEmpty(paraQueuePtr)) {printf("Error, empty queue\r\n");return NULL;}paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;return paraQueuePtr->nodes[paraQueuePtr->front];
}typedef struct AdjacencyNode {int column;struct AdjacencyNode* next;
}AdjacencyNode, *AdjacentNodePtr;typedef struct AdjacencyList {int numNodes;AdjacencyNode* headers;
}AdjacencyList, *AdjacencyListPtr;AdjacencyListPtr graphToAdjacentList(GraphPtr paraPtr) {int i, j, tempNum;AdjacentNodePtr p, q;tempNum = paraPtr->numNodes;AdjacencyListPtr resultPtr = (AdjacencyListPtr)malloc(sizeof(struct AdjacencyList));resultPtr->numNodes = tempNum;resultPtr->headers = (AdjacencyNode*)malloc(tempNum * sizeof(struct AdjacencyNode));//Fill the data.for (i = 0; i < tempNum; i ++) {//初始化头节点 p = &(resultPtr->headers[i]);p->column = -1;p->next = NULL;for (j = 0; j < tempNum; j ++) {if (paraPtr->connections[i][j] > 0) {//Create a new node.q = (AdjacentNodePtr)malloc(sizeof(struct AdjacencyNode));q->column = j;q->next = NULL;//Link.p->next = q;p = q;}}}return resultPtr;
}void printAdjacentList(AdjacencyListPtr paraPtr) {int i;AdjacentNodePtr p;int tempNum = paraPtr->numNodes;printf("This is the graph:\r\n");for (i = 0; i < tempNum; i ++) {p = paraPtr->headers[i].next;while (p != NULL) {printf("%d, ", p->column);p = p->next;}printf("\r\n");}
}//广度优先 
void widthFirstTranverse(AdjacencyListPtr paraListPtr, int paraStart){printf("width first \r\n");//Use a queue to manage the pointersint i, j, tempNode;AdjacentNodePtr p;i = 0;//Initialize datavisitedPtr = (int*) malloc(paraListPtr->numNodes * sizeof(int));for (i = 0; i < paraListPtr->numNodes; i ++) {visitedPtr[i] = 0;}//Of for iQueuePtr tempQueuePtr = initQueue();printf("%d\t", paraStart);visitedPtr[paraStart] = 1;enqueue(tempQueuePtr, paraStart);while (!isQueueEmpty(tempQueuePtr)) {tempNode = dequeue(tempQueuePtr);for (p = &(paraListPtr->headers[tempNode]); p != NULL; p = p->next) {j = p->column;if (visitedPtr[j]) continue;printf("%d\t", j);visitedPtr[j] = 1;enqueue(tempQueuePtr, j);}}printf("\r\n");
}void testGraphTranverse() {int i, j;int myGraph[5][5] = { {0, 1, 0, 1, 0},{1, 0, 1, 0, 1}, {0, 1, 0, 1, 1}, {1, 0, 1, 0, 0}, {0, 1, 1, 0, 0}};int** tempPtr;printf("Preparing data\r\n");tempPtr = (int**)malloc(5 * sizeof(int*));for (i = 0; i < 5; i ++) {tempPtr[i] = (int*)malloc(5 * sizeof(int));}for (i = 0; i < 5; i ++) {for (j = 0; j < 5; j ++) {tempPtr[i][j] = myGraph[i][j];}}printf("Data ready\r\n");GraphPtr tempGraphPtr = initGraph(5, tempPtr);AdjacencyListPtr tempListPtr = graphToAdjacentList(tempGraphPtr);printAdjacentList(tempListPtr);widthFirstTranverse(tempListPtr, 4);
}int main(){testGraphTranverse();return 1;
}

测试结果

Preparing data
Data ready
This is the graph:
1, 3,
0, 2, 4,
1, 3, 4,
0, 2,
1, 2,
width first
4       1       2       0       3


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

相关文章

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

目录 什么是邻接表&#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…

数字信号处理基础(二):FFT和IFFT的使用以及详细分析代码书写思路

目录 1. fft和ifft的原理1.1 fft1.2 ifft 2. 书写代码思路3. 完整代码4. 结果图 1. fft和ifft的原理 1.1 fft fft是快速傅里叶变换&#xff0c;是MATLAB中计算信号频谱的函数&#xff0c;使用方法是fft(x)&#xff0c;直接对信号x进行fft计算。 由于fft函数计算信号的频谱是0…

信号处理中的反傅里叶变换(IFFT)原理

信号处理中&#xff0c;经常需要将信号转换到频域进行分析&#xff0c;有时候还会从频域转回时域&#xff0c;用到FFT和IFFT函数。 FFT变换是将信号从时域转换到频域&#xff0c;在时域看起来复杂的信号转换到频域看起来就方便容易了很多。但有时候也需要将频域信号转换到时域…

adb下载、安装、环境配置

一&#xff1a;adb安装 adb下载链接&#xff1a;https://pan.baidu.com/s/1Vd6KyZ6vT2Qtmhazwre4OQ 提取码&#xff1a;3dx1 安装&#xff1a; 1.双击adb.exe文件&#xff0c;并运行。 2.添加环境变量&#xff1a; 右击计算机–属性—高级系统设置—高级—环境变量—新建&…

windows下载安装adb(极其简单)

单独安装adb&#xff0c;不安装sdk 下载adb Google很好的心&#xff0c;直接放出ADB的档案供人下载。下档路径如下&#xff1a; Windows版本&#xff1a;https://dl.google.com/android/repository/platform-tools-latest-windows.zip Mac版本&#xff1a;https://dl.google…

ADB-adb命令安装app

下载adb 安装adb 将名称中含有adb的文件&#xff0c;和fastboot.exe复制到 c:/windows/system32目录将名称中含有adb的所有文件复制到 c:/windows/system目录将adb.exe和AdbWinApi.dll复制到c:/windows/SysWoW64目录 有线安装apk 连接上数据线&#xff0c;然后把手机开发者模…

adb详细教程(一)-下载安装与环境变量配置

对于Android开发来说&#xff0c;adb是再熟悉不过的调试工具 但其实对于移动端的测试来说&#xff0c;adb也是一个十分重要的、能够提高测试工作效率的工具。 文章目录 一、介绍二、下载地址三、安装四、配置环境变量 一、介绍 全称 adb全称全称为Android Debug Bridge&#x…

mac下载安装adb环境

目录 方法一1、下载安装包2、下载完成后进行解压&#xff0c;目录路径注意不得包含中文3、配置环境变量4、验证安装是否成功 方法二1、安装homebrew2、安装adb3、运行adb 方法一 1、下载安装包 安装包下载地址 &#xff1a;https://developer.android.com/studio/releases/pl…

adb工具下载安装

一、adb环境配置 adb即Android Debug Bridge&#xff0c;就是可以通过窗口命令&#xff0c;使在pc端可以调试安卓移动端的一个工具包 我这里是默认电脑已经安装SDK的&#xff0c;如果没有也没关系&#xff0c;直接网上下载一个adb工具包一样的https://developer.android.goo…

adb环境配置

adb环境配置 1.下载工具包 工具包&#xff1a;platform-tools_r30.0.4-windows.zip 获取途径1&#xff1a;链接: https://pan.baidu.com/s/17BiARFlgsQa2wDETmoJIvQ?pwddsd2 提取码: dsd2 获取途径2&#xff1a;https://developer.android.google.cn/studio/releases/plat…