同一张表两方各字段相同_带你解读图的邻接矩阵和邻接表的变换

01 知识框架

203c2f668b48fb43d70dad867a912f64.png

02 图结构的存储

1

邻接矩阵法

有向图、无向图和网对应的邻接矩阵如下图所示:

abc5204047e19b45223d3ddbac3629fe.png f6389abc3361d27c67bd43451e83bb42.png 259b8d0efd76151db7849b654bd71792.png

邻接矩阵存储结构的定义如下:

#define MaxVertexNum 100  //顶点数目的最大值typedef char VertexType;  //顶点的数据类型typedef int EdgeType;  //带权图中边上权值的数据类型typedef struct{  VertexType Vex [MaxVertexNum] ; //顶点表    EdgeType Edge [MaxVertexNum] [MaxVertexNum];  //邻接矩阵,边表     int vexnum, arcnum;  //图的当前顶点数和弧数}MGraph;

2

邻接表法

图的邻接表存储方式:

b2bc0656c8628ee518b9ab0a58d3f705.png

邻接表的存储结构的定义如下:

typedef struct ArcNode{  int adjvex; //该边所指向结点的位置  struct ArcNode *next;指向下一条边的指针} ArcNode ;typedef struct{char data; //顶点信息ArcNode *firstarc //指向第一条边的指针}VNode;typedef struct{VNode adjlist[maxSize]; //邻接表int n,e; //顶点数和边数}AGraph;

算法1:将图的邻接矩阵表示法转换为邻接表表示法

思路:先初始化邻接表顶点,再利用嵌套循环遍历邻接矩阵,当邻接矩阵的某个位置有元素时,则将其链入相应的邻接表中。

void  AdjMatrixToAdjList( AdjMatrix gm, AdjList gl )//将图的邻接矩阵表示法转换为邻接表表示法。{  for (i=1;i<=n;i++)   //邻接表表头向量初始化。 {   scanf(&gl[i].vertex);    gl[i].firstarc=null;  }   for (i=1;i<=n;i++)     for (j=1;j<=n;j++)        if (gm[i][j]==1)       {         p=(ArcNode *)malloc(sizeof(ArcNode)) ;//申请结点空间。         p->adjvex=j;         p->next=gl[i].firstarc;          gl[i].firstarc=p; //链入顶点i的邻接点链表中        } }

算法2:将图的邻接表转换成邻接矩阵的算法

思路:转化分两步,一个是顶点数组,一个是邻接矩阵。顶点数组直接循环邻接表的顶点数组赋值,邻接矩阵则需要对每一个顶点结点的firstArc进行判断,如果不是null就把邻接矩阵相应位置赋值为1,表示顶点之间有边,直到该顶点的next是null。

void  AdjListToAdjMatrix(AdjList gl, AdjMatrix gm)//将图的邻接表表示转换为邻接矩阵表示。{  for (i=1;i<=n;i++)  //设图有n个顶点,邻接矩阵初始化。    for (j=1;j<=n;j++)        gm[i][j]=0;  for (i=1;i<=n;i++) {   p=gl[i].firstarc;  //取第一个邻接点。   while (p!=null)   {    gm[i][p->adjvex]=1;    p=p->next; }//下一个邻接点   }//for  }//算法结束}

3

十字链表

十字链表是有向图的一种链式存储结构。在十字链表中,对应于有向图中的每条弧有一个点,对应于每个顶点也有一个结点。这些结点的结构如下图所示。

1a7606b1c522923bf15da30e0c1c2ed7.png

弧结点中有5个域:尾域(tailvex) 和头域(headvex) 分别指示弧尾和弧头这两个顶点在图中的位置;链域hlink指向弧头相同的下一条弧;链域tlink指向弧尾相同的下一条弧;info域指向该弧的相关信息。这样,弧头相同的弧就在同一个链表上,弧尾相同的弧也在同一个链表上

顶点结点中有3个域:data域存放顶点相关的数据信息,如顶点名称;firstin和firstout两个域分别指向以该顶点为弧头或弧尾的第一个弧结点。

十字链表的表示方法如下:

84dd81212439add48a7ba781cdb3e288.png

注意:在十字链表中,既容易找到Vi为尾的弧,又容易找到Vi为头的弧,因而容易求得顶点的出度和入度。图的十字链表表示是不唯一的,但一个十字链表表示确定一个图。

4

邻接多重表

邻接多重表是无向图的另一种链式存储结构。在邻接表中,容易求得顶点和边的各种信息,但在邻接表中求两个顶点之间是否存在边而对边执行删除等操作时,需要分别在两个顶点的边表中遍历,效率较低。与十字链表类似,在邻接多重表中,每条边用一个结点表示,其结构如下所示。

a446d4bd8c253b284de43372da2418ae.png

弧结点中有5个域:尾域(tailvex) 和头域(headvex) 分别指示弧尾和弧头这两个顶点在图中的位置;链域hlink指向弧头相同的下一条弧;链域tlink指向弧尾相同的下一条弧;info域指向该弧的相关信息。这样,弧头相同的弧就在同一个链表上,弧尾相同的弧也在同一个链表上。

538397561ee3a34acec1d1d6b1b4efd6.png

其中,data域存储该顶点的相关信息,firstedge 域指示第一条 依附于该顶点的边。


在邻接多重表中,所有依附于同一顶点的边串联在同一链表中,由于每条边依附于两个顶点,因此每个边结点同时链接在两个链表中。对无向图而言,其邻接多重表和邻接表的差别仅在于,同一条边在邻接表中用两个结点表示,而在邻接多重表中只有一个结点。

无向图的邻接多重表表示如下:

11de6063d4da58e06a08c36a2000821a.png

a7b952a8bb619d0a8d0246bc6dd08590.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值