图的储存结构之邻接表

xiaoxiao2021-02-28  65

邻接表是图的一种链式储存结构。

在边数小于节点数的图中,如果继续使用邻接矩阵,那么就会造成资源浪费。比如我们有一个有图,一共五个节点,却只有4 条边,生成5*5的邻接矩阵时,此时在这25个内存空间中只有4个被有效的利用,这就造成了浪费。

这时,我们可以联想到链式结构。在前面的知识中,可以知道,链表相对与数组可以更有效的利用起内存空间,避免资源浪费。

因为链表是动态的,大小不用事先确定。

那么我们怎么用链表来表示图的呢?

在图中(下面说的图都为无向图),每个节点都会与一个或者多个节点连接,我们为每一个节点创建一个链表,以储存他们所连接的节点,可是我们知道,节点的next指针只能有一个,如果一个节点与多个节点连接,就会出现指针不够用的情况。为了解决这个问题,我们可以先建立一个结构体数组储存节点,再建立一个链表储存每个节点指向其他节点所在数组的下标。在结构体数组中,每个数组元素都包含着一个链表。如下图所示:

#include<iostream> using namespace std; const int MAXNUM = 100; typedef int DATETYPE; typedef struct ArcNode { int adjvex; //顶点下标,该边所指向的节点的位置 struct ArcNode *next; //指向下一边的指针 int info; //改边的相关信息(如权值),用的不多 }ArcNode; typedef struct VextexNode { DATETYPE date; //顶点信息 ArcNode *firstarc;//指向第一条边的指针 }VextexNode; typedef struct AdjListGraph { VextexNode adjlist[MAXNUM];//邻接表 int NumNodes, NumEdges;//顶点数和边数 }AdjListGraph; void Create(AdjListGraph &G) { int i, j, k; ArcNode *pev; cout << "请输入邻接表的顶点数以及边数(空格隔开):" << endl; cin >> G.NumNodes >> G.NumEdges; cout << "请输入每个顶点的值(回车):" << endl; for (i = 0; i < G.NumNodes; ++i) { cin >> G.adjlist[i].date; G.adjlist[i].firstarc = NULL; } for (k = 0; k< G.NumEdges; ++k){ cout << "输入边(vi,vj)的顶点序号i,j(空格分隔):"; cin >> i >> j; if (!(pev = (ArcNode *)malloc(sizeof(ArcNode)))) return; pev->adjvex = j;//邻接序号为j pev->next = G.adjlist[i].firstarc;//将pev指向当前顶点指向的顶点 G.adjlist[i].firstarc = pev; /*由于是无向的边,故将对j的操作对i进行一次*/ if (!(pev = (ArcNode *)malloc(sizeof(ArcNode)))) return; pev->adjvex = i; pev->next = G.adjlist[j].firstarc; G.adjlist[j].firstarc = pev; } } void main() { AdjListGraph G; Create(G); system("pause"); }

转载请注明原文地址: https://www.6miu.com/read-57254.html

最新回复(0)