图的邻接矩阵存储

邻接表的构造与邻接矩阵完全不同,同学们应该发现了,邻接表的的结构更像是由几个链表构成的。

在构造邻接表时,我们的确会借助链表的结构。对图中每个顶点的信息,我们都会分别使用一个链表来进行存储。

因此,我们需要初始化一个有 n 个元素的链表数组,n 为图中顶点数量。

我们要在邻接表中存储的图的信息,实际上就是顶点之间存在的有向边。

当从顶点 a 到顶点 b 存在一条有向边时,我们只需要在头结点为 a 的链表后插入一个结点 b。

值得注意的是,当一条边是从顶点 b 到顶点 a 时,我们同样需要在以 b 为头结点的链表后插入一个结点 a。

同样在输出邻接表的时候,我们也只需要把每个链表依次遍历输出就好了。

示例代码如下(C++ 版):

const int MAX_N = 100;
vector<int> adj[MAX_N];
void insert(int u, int v) {
    adj[u].push_back(v);
}
// 输出从 u 连出的所有边,顶点从 0 开始编号
for (int i = 0; i < adj[u].size(); ++i) {
    cout << "(" << u << ", " << adj[u][i] << ")" << endl;
}

除了通过vector(或 Java 中的ArrayList)实现以外,还可以直接用数组模拟链表来实现邻接表结构(常数相比使用vector来说更小,运行效率更高):

今天终于知道图的邻接表怎么用数组实现了。之前都是直接vector。

const int MAX_N = 100;
const int MAX_M = 10000;
struct edge {
    int v, next;
} e[MAX_M];

//存储边的索引
int p[MAX_N], eid;
void init() {
    memset(p, -1, sizeof(p));
    eid = 0;
}
void insert(int u, int v) {
    e[eid].v = v;   // 节点u的上一条边的索引
    e[eid].next = p[u];
    p[u] = eid++;
}
?
// 输出从 u 连出的所有边,顶点从 0 开始编号
for (int i = p[u]; i != -1; i = e[i].next) {
    cout << "(" << u << ", " << e[i].v << ")" << endl;
}
 

我们可以看到,邻接矩阵存储结构最大的优点就是简单直观,易于理解和实现。

其适用范围广泛,有向图、无向图、混合图、带权图等都可以直接用邻接矩阵表示。

另外,对于很多操作,比如获取顶点度数,判断某两点之间是否有连边等,都可以在常数时间内完成。

然而,它的缺点也是显而易见的:从以上的例子我们可以看出,对于一个有 n 个顶点的图,邻接矩阵总是需要 O(n?*n) 的存储空间。

当边数很少的时候,就会造成空间的浪费。

因此,具体使用哪一种存储方式,要根据图的特点来决定:如果是稀疏图(点多边少),我们一般用邻接表来存储,这样可以节省空间;

如果是稠密图(点少边多),当需要频繁判断图中的两点之间是否存在边时往往用邻接矩阵来存储,其他时候用邻接表或邻接矩阵皆可。

时间: 2024-10-16 11:39:00

图的邻接矩阵存储的相关文章

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

图的邻接矩阵存储数据结构--自己写数据结构

头文件graph.h #ifndef _GRAPH_H_ #define _GRAPH_H_ #define MAX_VER 100 #define ENDLESS 65535 typedef char VertexType; typedef int EdgeType; typedef struct _Graph { VertexType ver[MAX_VER]; EdgeType edge[MAX_VER][MAX_VER]; int num_ver,num_edge; }Graph,*pG

DS图—图的邻接矩阵存储及度计算

题目描述 假设图用邻接矩阵存储.输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度.出度和度,并输出图中的孤立点(度为0的顶点) --程序要求-- 若使用C++只能include一个头文件iostream:若使用C语言只能include一个头文件stdio 程序中若include多过一个头文件,不看代码,作0分处理 不允许使用第三方对象或函数实现本题的要求 输入 测试次数T,每组测试数据格式如下: 图类型  顶点数 (D—有向图,U—无向图) 顶点信息 边数 每行一条边(顶点1 顶

图的邻接矩阵存储结构

如上图,我们可以把v0标记为0,v1标记为1.... 并把联通的2点权值全设置为1,那么可以用邻接矩阵(右图)来表示 概念解析: 第一个邻接顶点: 我们以vo为例,第一个邻接顶点为V1(其实也可以使V3,只不过考虑计算机的存储顺序,我们找邻接顶点,一般是从v0扫描到v3,所以我们先在内存中扫描到v1) 下一个邻接顶点: 我们以v0为例,下一个邻接顶点就是v3(同样,其实也可以使V1,只不过考虑计算机的存储顺序,我们找下个邻接顶点,一般是从v2扫描到v3,之所以从v2扫描起,那是因为,V1已经是第

_DataStructure_C_Impl:图的邻接矩阵存储

//_DataStructure_C_Impl:邻接矩阵 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4]; typedef char InfoPtr; typedef int VRType; #define INFINITY 10000 //定义一个无限大的值 #define MaxSize 50 //最大顶点个数 typedef enum{DG,DN,

数据结构(二十九)图的邻接矩阵存储结构

一.邻接矩阵的Java语言代码实现: 二.邻接矩阵的创建C语言代码实现: #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXVEX 10

图的操作和l邻接矩阵存储

/* 1.图是由顶点集合及顶点之间的关系集合组成的一种数据结构.图的定义:G=(V,E) 2.顶点和边:图中的结点一般称作顶点,顶点与顶点相关联称作遍 3.完全图:在n个顶点的无向图中,若有n(n-1)/2条边,即任意两个顶点之间有且只有一条边,则称此图 为无向完全图:在n个顶点的右向图中,若有n(n-1)条边,即任意两个顶点之间有且只有方向相反的2条边, 则称此图为有向完全图. 4.顶点的度:顶点的度=出度+入度 5.连通图和强连通图: 在无向图中,若从顶点vi到顶点vj有路径,则称顶点vi和

图总结之存储结构代码详解

一.图的存储结构 1.1 邻接矩阵 图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 看一个实例,下图左就是一个无向图. 从上面可以看出,无向图的边数组是一个对称矩阵.所谓对称矩阵就是n阶矩阵的元满足aij = aji.即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的. 从这个矩阵中,很容易知道图中的信息. (1)要判断任意两顶点是否有

java 图的邻接矩阵

有向图 在有向图中,结点对<x ,y>是有序的,结点对<x,y>称为从结点x到结点y的一条有向边,因此,<x,y>与<y,x>是两条不同的边.有向图中的结点对<x,y>用一对尖括号括起来,x是有向边的始点,y是有向边的终点,有向图中的边也称作弧. 无向图 在无向图中,结点对(x,y)是无序的,结点对(x,y)称为与结点x和结点y相关联的一条边.(x,y)等价于<x,y>和<y,x>. 完全图 在有n个结点的无向图中,若有n