图的存储

邻接矩阵法

一维数组存顶点信息,二维数组(邻接矩阵)存边信息。

这里写图片描述
下面举例说明:
这里写图片描述
这里写图片描述

思考:要定义一个图的邻接矩阵存储,必须包含哪些内容?
前面说过,邻接矩阵存储即:一维数组存顶点,二维数组存边(顶点间)。由此,我们想到一个顶点表(一维数组),一个边表(二维数组)。但因为图是任意的,所以我们又想到当前要定义的图必须有一个当前图的顶点数和边数。这样我们可以用一个结构体来描述。

邻接矩阵存储结构定义:

    typedef struct{
      char Vertex[10];       //顶点表(这里顶点类型定义为char)
      int Edge[10][10];       //邻接矩阵表(这里边的权值类型定义为int)
      int vexnum,edgenum;     //当前图的顶点数,边数
}

小结:
(1)空间复杂度:O(|V|^2);——–适合稠密图存储
(2)无向图:第i个顶点的度=第i行(或列)非0元素个数;
(3)有向图:第i个顶点的出度=第i行非0元素个数;第i个顶点的入度=第i列非0元素个数;
(4)设图邻接矩阵为A,A^n[i][j]=Vi到Vj的长度为n的路径的数目。

邻接表法

对图的每个顶点建立一个单链表。
所以:邻接表法涉及顶点表和边表。其中顶点表结点包含顶点和边表头指针,采用顺序存储方式;边表结点包含邻接点和指针域,采用链式存储方式。

下面举例说明:
这里写图片描述
note:
(1)边表结点个数一定是偶数,=边数*2;
(2)一条边存两次;
(3)空间复杂度:O(|V|+2|E|);
(4)第i个单链表的结点表示依附于Vi的边;
这里写图片描述
note:
(1)边表结点个数=边数;
(2)一条边存一次;
(3)空间复杂度:O(|V|+|E|);
(4)第i个单链表的结点表示以Vi为尾的弧;

思考:要定义一个图的邻接表法存储,必须包含哪些内容?
前面说过邻接表法包含顺序存储的顶点表结点和链式存储的边表结点,那么我们先来看如何存储顶点表结点?
顶点表结点包含顶点域和指向边表头结点的指针域,由此推出用结构体存储顶点表结点,其中顶点域类型为基本数据类型,int或char均可;而指向边表头结点的指针域的指针类型自然是边表头结点的指针类型,因此我们必须先定义边表结点,再定义顶点表结点。如何定义边表结点?
边表结点包含邻接点域和指向下一条边的指针域,由此推出用结构体存储边表结点。邻接点域与顶点表中顶点域一样处理。指向下一条边的指针域的指针类型是边表结点类型。

从而,我们知道:先定义边表结点,边表结点中的指针类型应是指向自身的结构体指针类型;再定义顶点表结点,顶点表结点中的指针类型应是指向边表结点的结构体类型。这就是邻接表的定义。最后,因为图是任意的,所以我们又想到当前要定义的图必须有一个当前图的顶点数和边数。因此,一个具体的图的邻接表法定义包含邻接表定义和顶点数边数,这样就可以用结构体来定义一个图的邻接表法。

typedef struct ArcNode{      //边表结点
    int adjvex;//邻接点域
    struct ArcNode *next;//指向下一个边表结点的指针
}ArcNode;
typedef struct VerNode{       //顶点表结点
    int verdata;//顶点域
    struct ArcNode *firstArc;//指向第一个边表结点的指针
}VerNode,AdjList[10];
typedef struct{
    AdjList vertices;//邻接表
    int vexnum,arcnum;//当前图的顶点数和边数
}ALGraph;

小结:
(1)邻接表法适合稀疏图存储;
(2)邻接表表示不唯一,因为边表中结点次序任意。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值