图基础【C语言】

文章介绍了图的概念,包括无向图和有向图,以及图的存储结构如邻接矩阵和邻接表。讨论了深度优先遍历(DFS)和广度优先遍历(BFS)两种图的遍历方法,并通过例子展示了如何进行DFS和BFS。此外,文章还提到了生成树和最小生成树的概念,以及Prime算法在寻找最小生成树中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础概念

  • 假设ABCDEFG是7个电话,之间的连线表示修有通信线路
  • 电话就是图的顶点vi∈V,通信线路是边ei∈E,G={V,E}就是一个图
  • 只要两个电话间有线路,就可以互相通话=>无向图
  • 某个电话(顶点)连接的线路(边)数量:
  • ABCDE和GF之间的消息无法传递:不连通
  • ABCDE和GF是两个连通分量

  •  假设ABCDE是五个电话,之间的连线表示修有通信线路,数字表示该线路的电话费

  •  假设ABCDE是五个城市,带箭头连线表示该方向上有航班运营
  • 例如航班A→D只能支持A飞往D,边是单向的=>有向图
  • 飞来某地的航班数量:入度
  • 从某地起飞的航班数量:出度

  • 在一个无向图中,所有的顶点的度数之和为边数量的2倍
  •  在一个有向图中,所有顶点的出度之和等于所有顶点入度之和

例题:

1.无向图G={V,E}中,|V|=n,则|E|最大为?

分析:

n个结点,每个结点都与除自己外其他结点有一条边相连,而一条边连接了两个结点,因此答案为:n(n-1)/2

答案:n(n-1)/2

图的存储结构

邻接矩阵

  • 设|V|=n,图可用一个n*n方阵表示,即一个二维数组AdjMat[n][n]
  • AdjMat[i][j]表示vi到vj的邻接情况

无向无权图:

  • AdjMat[i][j]为1表示有边相连,为0表示无边
  • AdjMat是对称的
    所以设无向图对应的邻接矩阵为 A,则 A 中第 i 行上非 0 元素的个数等于第 i 列上非 0 元素的个数

有向加权图:

  • AdjMat[i][j]表示vi→vj的权重
  • AdjMat[i][j]为+∞表示不通

 邻接表

  • 每个顶点用一个链表存下自己的邻居
  • |V|=n,有n个链表,即图可用一个链表的数组AdjList[n]存储
  • AdjList[i]表示顶点vi的链表(头)
  • 从AdjList[i]开始可以遍历所有以vi的邻居

 

  • 设某有向图的邻接表中有 n 个表头结点和 m 个表结点,则该图中有m条有向边
     

 邻接矩阵和邻接表的比较

  • 设G={V,E}中,|V|=n.
  • 邻接矩阵无论如何都需要一个二维数组[n][n],而邻接表中的每条链表长度取决于它有多少邻居
  • 邻接矩阵访问AdjMat[i][j]多少O(1)D的,但邻接表访问特定边需要顺着起点的链表向后查找

  • 邻接表优点:在边较少时节省许多空间=>适用于稀疏图
  • 邻接表缺点:无法直接获得某条边信息,需要vi链表进行从头顺序存取,最坏O(n)

图的DFS与BFS遍历

DFS:深度优先遍历

  • 遇到新的邻居就进去...直到没有可以进的邻居了再返回
  • 优先进入后来遇到的邻居=>递归/栈
  • 相当于二叉树的先序遍历

以B为起点进行DFS:

访问B

       访问B的下一个未被访问邻居D

              访问D的下一个未被访问邻居C

                      C所有邻居都被访问过了,返回

              访问D的下一个未被访问邻居A

                      A所有邻居都被访问过了,返回

                访问D的下一个未被访问邻居E

                       E所有邻居都被访问过了,返回

                D所有邻居都被访问过了,返回

           B所有邻居都被访问过了,当前连通图遍历完毕

BFS【Breath First Search】:广度优先遍历

  • 先把当前结点的邻居都遍历完,再按先来后到遍历邻居的邻居们,逐层向外扩张
  • 相当于二叉树的层序遍历
  • 优先进入先访问的邻居的邻居=>队列

 以B为起点进行BFS:

  • 将起点B入队
  • 访问当前队首B,它出队,未访问邻居D,E入队
  • 访问当前队首D,它出队,未访问邻居A,C入队
  • 访问当前队首E,它出队,它没有未访问邻居了
  • 访问当前队首A,它出队,它没有未访问邻居了
  • 访问当前队首C,它出队,它没有未访问邻居了
  • 队列空了,当前连通图遍历完毕

要点:

  • DFS每步操作:进入当前结点下一个未访问的邻居,如无则返回
  • BFS每步操作:进入当前队首结点并让其出队,将其未访问邻居入队

1.给定如下邻接矩阵,写出由v0出发的一个DFS序列:________

A.0243156

B.0136542

C.0134256

D.0361542

 分析:

(1)无需画出图结构

(2)标注已遍历过的结点

0 1 3 4 2 5 6

答案:C

 2.给定如下邻接表,则由v0出发的深度优先遍历结果为(),广度优先遍历结果为()

A.0132                 B.0231             C.0321                D.0123

答案:D   D

生成树

  • 对于含n个结点的一个无向连通图,其边数最多为n(n-1)/2条,最少为n-1条
  • 保持连通性的情况下,选n-1条边出来,剔除其他边,它就变成了一棵树
  • 生成树里没有环
  • n结点+n-1条边+连通=>生成树

=>

最小生成树(MST)

概念:

在加权图中选出n-1条边来构成其生成树,且这些边的权值之和最小

 

  •  MST不一定唯一(如权值全相同)

求最小生成树:Prime算法

  • 每次在连接已完成结点和未完成结点的边中,选一条权值最小的,重复n-1遍
  • 算法利用了贪心思想:选择局部最优

 

            

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值