【图】邻接表

article/2025/8/27 19:40:32

目录

无向图的邻接表

 链表(存相邻顶点下标)的类

数组里放的顶点

邻接表(操作)

构造和析构(创建销毁邻接表)

插入顶点

插入边

获取下标

插v1、v2之间的边

删除顶点

删除边

输出:

其他图邻接表


         

        邻接表用一个一维数组存图的顶点和指针,指针指向一个链表,链表里存放与当前顶点相连的顶点在数组中的下标。如下图(无向图邻接表):

无向图的邻接表

 链表(存相邻顶点下标)的类

class Edge
{
public:Edge() :m_next(nullptr) {}Edge(int v) :m_destindex(v), m_next(nullptr) {}int m_destindex;//下标Edge* m_next;//下一个邻接顶点的结点
};

数组里放的顶点

class Vertex
{
public:Vertex() :m_list(nullptr) {}Vertex(int v) :m_VerValue(v), m_list(nullptr) {}char m_VerValue;//顶点值Edge* m_list;//指针指向邻接顶点的链表
};

邻接表(操作)

插入顶点,插入边,删除顶点,删除边,获取顶点在数组中的下标(前面的操作需要用)

#define SIZE 10
class GraphLink
{
public:GraphLink();~GraphLink();void InsertVertex(char v);//插顶点void InsertEdge(char v1, char v2);//插边void PrintGraph();//打印void DelVertex(char v);//删顶点void DelEdge(char v1, char v2);//删边int GetVertexIndex(char v);//获取顶点下标
private:int m_MaxVertex;//最多结点数int m_NumVertex;//当前结点数int m_NumEdge;//边数Vertex* m_VerArr;//存顶点的数组(指针指向数组头)
};

构造和析构(创建销毁邻接表)

创建:给m_VerArr指针new最大顶点数m_MaxVertex个顶点Vertex大小的空间;

销毁:释放指向数组起始的指针的空间。

GraphLink::GraphLink() :m_MaxVertex(SIZE), m_NumVertex(0), m_NumEdge(0)
{m_VerArr = new Vertex[m_MaxVertex];
}
GraphLink::~GraphLink()
{if (m_VerArr != nullptr){delete[]m_VerArr;m_VerArr = nullptr;}
}

插入顶点

        首先确定顶点数(不能超过设定的最大顶点数)。

        若可插:将顶点值赋到数组中最后一个位置m_VerArr[m_NumVertex],顶点个数++。

void GraphLink::InsertVertex(char v)
{if (m_NumVertex >= m_MaxVertex)return;m_VerArr[m_NumVertex++].m_VerValue = v;
}

插入边

插入顶点v1到顶点v2的边时,由于链表中记录的是顶点的下标,所有首先需要有一个获取下标的函数:

获取下标

        遍历数组记录下标,找到顶点即可找到下标返回,若没找到:返回-1。

int GraphLink::GetVertexIndex(char c)
{for (int i = 0; i < m_NumVertex; i++){if (m_VerArr[i].m_VerValue == c)return i;}return -1;
}

插v1、v2之间的边

        注意:无向图插一条边需要改两个表。

获取下标后,插入方法与链表头插相同。

void GraphLink::InsertEdge(char v1, char v2)
{int p1 = GetVertexIndex(v1);int p2 = GetVertexIndex(v2);if (p1 == -2 || p2 == -1)return;//v1->v2 既是在v1的边链表中插入值为p2的边节点Edge* edge = new Edge(p2);edge->m_next = m_VerArr[p1].m_list;m_VerArr[p1].m_list = edge;//v2->v1edge = new Edge(p1);edge->m_next = m_VerArr[p2].m_list;m_VerArr[p2].m_list = edge;m_NumEdge++;
}

删除顶点

用覆盖删除的方法:数组最后一个顶点覆盖要删的,并修改链表内受影响下标的值。

void GraphLink::DelVertex(char v)
{int p = GetVertexIndex(v);if (p == -1)return;Edge* pp = m_VerArr[p].m_list;char destvalue;while (pp){destvalue = m_VerArr[pp->m_destindex].m_VerValue;DelEdge(v, destvalue);pp = m_VerArr[p].m_list;}//覆盖m_NumVertex--;m_VerArr[p].m_VerValue = m_VerArr[m_NumVertex--].m_VerValue;//修改Edge* q = nullptr;pp = m_VerArr[p].m_list;while (pp != nullptr){int k = pp->m_destindex;q = m_VerArr[k].m_list;while (q){if (q->m_destindex == m_NumVertex){q->m_destindex = p;break;}q = q->m_next;}pp = pp->m_next;}
}

删除边

void GraphLink::DelEdge(char v1, char v2)
{int p1 = GetVertexIndex(v1);int p2 = GetVertexIndex(v2);if (p1 == -2 || p2 == -1)return;//在p1里面删p2Edge* pf = m_VerArr[p1].m_list;if (m_VerArr[p1].m_list->m_destindex == p2){m_VerArr[p1].m_list = m_VerArr[p1].m_list->m_next;delete pf;pf = nullptr;}else{while (pf->m_next->m_destindex != p2 && pf != nullptr){pf = pf->m_next;}if (pf == nullptr)return;Edge* p = pf->m_next;pf->m_next = p->m_next;delete p;p = nullptr;}//v2->v1pf = m_VerArr[p2].m_list;if (m_VerArr[p2].m_list->m_destindex == p1){m_VerArr[p2].m_list = m_VerArr[p2].m_list->m_next;delete pf;pf = nullptr;}else{while (pf->m_next->m_destindex != p1 && pf != nullptr){pf = pf->m_next;}if (pf == nullptr)return;Edge* p = pf->m_next;pf->m_next = p->m_next;delete p;p = nullptr;}m_NumEdge--;
}

输出:


void GraphLink::PrintGraph()
{Edge* p = nullptr;for (int i = 0; i < m_NumVertex; i++){cout << i << " " << m_VerArr[i].m_VerValue << " ";p = m_VerArr[i].m_list;while (p){cout << p->m_destindex << "->";p = p->m_next;}cout << "nul" << endl;}cout << endl;
}

其他图邻接表

        有向图注意边的数量修改,网需要在链表结点中加上存边权值的部分。

 网结构如下:

 

 


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

相关文章

图的邻接表表示法(C语言)

邻接表 邻接表数据结构类型如下&#xff1a; #define MaxVertices 100 typedef struct node{ //边表 int adjvex;node* next; }EdgeNode; typedef struct{ //顶点表 int vertex; EdgeNode* edgenext; }VertexNode; typedef VertexNode AdjList[MaxVertices];//…

邻接表的创建

邻接表 特点&#xff1a; 1、想要知道某个顶点的度&#xff0c;就去查找这个顶点的边表中结点的个数 2、若想判断顶点 Vi 到 Vj是否存在边&#xff0c;只需测试顶点 Vi 的边表中adjvex是否存在 Vj 的下标。 3、若求顶点的所有邻接点&#xff0c;其实就是对此顶点的边表进行遍历…

邻接表创建

邻接矩阵是个不错的图储存结构&#xff0c;但我们发现&#xff0c;对于边数相对顶点较少的图&#xff0c;这种结构是存在对储存空间的极大浪费的&#xff08;关于邻接矩阵的相关知识在这里&#xff1a;邻接矩阵的创建&#xff09;&#xff0c;因此我们要考虑另外一种存储结构方…

邻接表和邻接矩阵

进入图论的大门&#xff08;深渊&#xff09;之前&#xff0c;我们一定要掌握的两种必备手段——邻接表和邻接矩阵&#xff0c;此刻将成为我们的巨大帮手&#xff08;其实做不来题还是做不来&#xff09;&#xff0c;下面让我们来学习一下&#xff0c;这两种存图方式在计算机中…

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

欢迎关注“软件开发理论”公众号获取干货 图的存储结构主要分两种&#xff0c;一种是邻接矩阵&#xff0c;一种是邻接表。 1.邻接矩阵 图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息&#xff0c;一个二维数组&#xff08;邻接矩阵&#xff09;存储图…

无向图邻接表实现

无向图邻接表实现 顶点&#xff1a;按照编号顺序将顶点数据存储在一维数组当中 关联同一个顶点的边&#xff08;以顶点为尾的弧&#xff09;&#xff1a;用线性链表存储 头结点&#xff1a;datafirstarc 表结点&#xff1a;adjvex&#xff08;邻接点的序号&#xff0c;存放…

邻接矩阵和邻接表

图的存储结构主要分两种&#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…