分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_图

01 基本概念

1、图的定义

图G(Graph)由顶点的有限集合V(G)和两个不同顶点的边的有限集合 E(G)构成,记为 G=(V,E)。

02 图的存储

2、图的存储结构

  • 邻接矩阵

  • 邻接表

a25e833e3b4b5dadb0f2e4d78862cb99.png

a、邻接矩阵存储方法

邻接矩阵:顶点之间相邻关系的矩阵。

图G(V,E)含 n(n>0)个顶点,则G的邻接矩阵A是 n 阶方阵;其中顶点编号为 

0 ~(n-1)。

共有四种类型

  • 不带权无向图

  • 不带权有向图

  • 带权无向图

  • 带权有向图

b4ba6a23b0a0fb2b830473fa886e6ab4.png

邻接矩阵定义

66f6dff752cfcc2d95b6e8eb0db96c16.png

邻接矩阵

理解

E(G1)=

{(1,2),(1,3),(1,0),(2,3),(3,0),(2,4),(3,4),(4,0)}

它的邻接矩阵A1

  • G1共5个顶点,即为5阶矩阵

  • 无向边 (i,j)∈E(G) 共两条

  • 存在一条边,则A[i][j]的值为1,否则为0

E(G3)=

{<0,1>,<0,3>,<1,2>,<2,4><3,2>}

它的邻接矩阵A3

  • G3共5个顶点,即为5阶矩阵

  • 有向边 ∈E(G)共一条

  • 存在一条有向边,则A[i][j]的值为边的权重

邻接矩阵的特点

  • 图的邻接矩阵表示是唯一的

  • 存储空间固定 O(n2),适合存储稠密图

  • 无向图的邻接矩阵一定是对称矩阵

  • 无向图的邻接矩阵i行(或i列)非零元素(或非∞元素)的个数为顶点i的度

  • 有向图的邻接矩阵i行(或i列)非零元素(或非∞元素)的个数为顶点i的出、入度

  • 此方法容易确定两个顶点之间是否有边

数据类型定义

#define MAXV  typedef struct{  int no;//顶点编号  InfoType info;//顶点其它信息}VertexType;//顶点类型typedef struct{  int edges[MAXV][MAXV];//邻接矩阵边数组  int n,e;//顶点数、边数  VertexType vexs[MAXV];//顶点信息}MGraph;//图的邻接矩阵类型

b、邻接表存储方法

邻接表:由顺序分配与链式分配结合。

图G(V,E)含 n(n>0)个顶点;每个顶点建立一个单链表,单链表中的节点代表依附于该顶点的边;每个单链表附设一个表头节点。

cdfa5cd061778a8bd235b720cc10049f.png

c3f8147f093f872558ec393403fad3f8.png

图G1的节点

0e2e3df6b13d22ece2ec6139abab7e2c.png

图G1的邻接表构成

邻接的特点

  • 图的邻接表表示不唯一

  • 邻接表适合存储稀疏图

  • 无向图的邻接表的顶点对应的的边节点数为顶点的度

  • 有向图的邻接表的顶点对应的的边节点数为顶点的出度

数据类型定义

typedef struct ANode{  int adjvex;//该边的终点编号  struct ANode * nextarc;//指向下一条边的指针  InfoType info;//该边的相关信息}ArcNode;//边节点类型typedef struct Vnode{  Vertex data;//顶点信息  ArcNode * firstarc;//指向第一条边}VNode;//邻接表头节点类型typedef VNode AdjList[MAXV];//邻接表类型typedef struct{  AdjList adjlist;//邻接表  int n,e;//顶点数、边数}ALGraph;//图的邻接表类型

03 图的遍历

3、图的遍历概念

从指定的顶点出发,沿着图的边访问图中所有节点,每个节点仅被访问一次。

分类

  • 深度优先(DFS)

  • 广度优先(BFS)

a、深度优先

从初始顶点出发,先访问初始顶点,再访问与初始顶点相邻且没被访问过的顶点;递归以上逻辑,直到每个节点都被访问。

邻接表实现DFS

void DFS(ALGraph *G, int v){  ArcNode *p;  visited[v]=1;  printf("%d",v);  p=G->adjlist[v].firstarc;  while(p!=NULL)  {    if(visited[p->adjvex]==0)      DFS(G,p->adjvex);    p=p->nextarc;  }}

以图G1的邻接表顶点2进行深度优先遍历

访问序列为(2、1、0、3、4)

5d5818eac3b3f6c7935c76812b562bf9.png

深度优先执行过程

b、广度优先

从初始顶点出发,按顺序访问所有与初始顶点相邻的顶点;再按初始顶点访问的顺序,依次访问每个顶点所有未被访问过的相邻顶点。

邻接表实现BFS

void BFS(ALGraph *G, int v){  ArcNode *p;  int queue[MAXV], front=0, rear=0;  int visited[MAXV];  int w,i;  for(i=0;in;i++)    visited[i]=0;  printf("%2d",v);  visited[v]=1;  rear=(rear+1) % MAXV;  queue[rear] = v;  whiel(front!=rear)  {    front = (front+1)%MAXV;    w=queue[front];    p=G->adjlist[w].firstarc;    while(p!=NULL)    {      if(visited[p->adjvex]==0)      {        printf("%2d",p->adjvex);        visited[p->adjvex]=1;        rear=(rear+1)%MAXV;        queue[rear]=p->adjvex;      }      p=p->nextarc;    }  }  printf("\n");}

以图G1的邻接表顶点2进行广度优先遍历

访问序列为(2、1、3、4、0)

ad3b3446b877af56f0a99fee0c4d6ee1.png

7ab398738a656051dea45e702e78e150.gif

版权说明:

封面图片来自网络,侵删。

原创文章,只供学习交流。

参考《数据结构教程 第4版》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值