数据结构之图 和问答题
目录
图的定义和术语
邻接点、度、入度、出度 路径、路径长度、简单路径、简单回路 连通图、连通分量、强连通图、强连通分量 生成树、生成森林
图:记为 G=( V, E ) 其中:V 是G的顶点集合,是有穷非空集; E 是G的边集合,是有穷集。
有向图 图G中的每条边都是有方向的; 无向图 图G中的每条边都是无方向的; 完全图 图G任意两个顶点都有一条边相连接;
稀疏图:边较少的图。通常边数<<n2 稠密图:边很多的图。无向图中,边数接近n(n-1)/2 ; 有向图中,边数接近n(n-1)
图的存储结构
图的特点:非线性结构(m :n )邻接矩阵(数组)表示法 邻接表(链式)表示法
邻接矩阵(适合稠密图)
用矩阵来表示图中顶点之间的邻接关系。借助邻接矩阵容易判定任意两个顶点之间是否有边或弧相连,并容易求得各个顶点的度。 ① 对于无向图,顶点vi的度是邻接矩阵中第i行(第i列)的元素之和。 ② 对于有向图,顶点vi的出度OD(vi)是第i行的元素之 和。顶点vj的入度ID(vj)是第j列的元素之和。 存储表示定义如下: 用邻接矩阵表示图,除了存储用于表示顶点之间相邻关系的邻接矩阵外,还需用一个顺序表存储顶点信 息。
邻接表表示法
①无向图的邻接表中结点个数是边数的两倍。 ②在无向图的邻接表中,顶点vi的度恰为第i个链表中 的结点个数。 ③在有向图的邻接表中,第i个单链表中的结点个数只 是顶点vi的出度。 ④顶点的入度值不容易得出。为了便于确定顶点vi的入度,则建立一个以顶点vi为头的弧的单链表,称为有 向图的逆邻接表。
邻接表特点:空间效率高;容易寻找顶点的邻接点
缺点:判断两顶点间是否有边或弧,需搜索两结点对应的单链表,没有邻接矩阵方便。
图的遍历
遍历定义:从已给的连通图中某一顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历,它是图的基本运算。
一、深度优先搜索 递归 栈
通图的深度优先搜索遍历:从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到。
二、广度优先搜索 层次遍历 队列
简单归纳: 在访问了起始点v之后,依次访问 v的邻接点; 然后再依次访问这些顶点中未被访问过的邻接点; 直到所有顶点都被访问过为止。
连通网的最小生成树
生成树:是一个极小连通子图,它含有图中全部顶点,但只有n-1条边。 生成森林:由若干棵生成树组成,含全部顶点,但构成这些树的边是最少的。
Kruskal算法特点:将边归并,适于求稀疏网的最小生成树。算法采用邻接表作为图的存储表示 Prime算法特点: 将顶点归并,与边数无关,适于稠密网。邻接矩阵作为图的存储表示 这两个算法,都是利用MST 性质来构造最小生成树的。
Kruskal算法 O(eloge)
(简单的说就是找不围成圈的最小的边) 步骤: (1) 首先构造一个只有n个顶点但没有边的非连通图T={V,}, 图中每个顶点自成一个连通分量。 (2) 当在边集 E 中选到一条具有最小权值的边时,若该边的两个顶点落在T中不同的连通分量上,则将此边加入到生成树的边集合T 中;否则将此边舍去,重新选择一条权值最小的边。 (3) 如此重复下去,直到所有顶点在同一个连通分量上为止。此时的T即为所求(最小生成树)
Prime算法 O(n2)
(简单的说就是一直加点) 取图中任意一个顶点 v 作为生成树的根,之后往生成树上添加新的顶点 w。添加顶点w的条件为:w 和已在生成树上的顶点v 之间必定存在一条边,并且该边的权值在所有连通顶点 v 和 w 之间的边中取值最小。之后继续往生成树上添加顶点,直至生成树上含有 n-1 个顶点为止。
单源最短路径
两种常见的最短路径问题:
一、 单源最短路径—用Dijkstra(迪杰斯特拉)算法
(1)初始时,S只包含源点v,即S=v。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或(若u不是v的出边邻接点)。
(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
(3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
(4)重复步骤(2)和(3)直到所有顶点都包含在S中。
二、所有顶点间的最短路径—用Floyd(弗洛伊德)算法
拓扑排序
拓扑排序算法:重复选择没有直接前驱的顶点。
① AOV网(Activity On Vertices)—用顶点表示活动的网络 AOV网定义:若用有向图表示一个工程,在图中用顶点表示活动,用弧表示活动间的优先关系。Vi 必须先于活动Vj 进行。则这样的有向图叫做用顶点表示活动的网络,简称 AOV。 ② AOE网(Activity On Edges)—用边表示活动的网络 AOE网定义:如果在无环的带权有向图中, 用有向边表示一个工程中的活动,用边上权值表示活动持续时间,用顶点表示事件,则这样的有向图叫做用边表示活动的网络,简称 AOE。
AOE网络的用途:常用于大型工程的计划管理。利用AOE网络可以解决以下两个问题:
(1) 完成整个工程至少需要多少时间。 (假设网络中没有环)? (2) 为缩短完成工程所需的时间, 应当加快哪些活动? 或者说,哪些活动是影响工程进度的关键?
关键路径
完成整个工程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的持续时间之和。这条路径长度最长的路径就叫做关键路径(Critical Path)。
构造关键路径的方法:要用到拓扑排序和逆拓扑排序
广义表
广义表的定义
广义表的特性 ① 广义表是一种线性结构,表中数据元素彼此间有固定的相对次序;广义表的长度定义为最外层包含的元素个一种图形表示。 广义表的深度定义为所含括弧的重数;注意:“原子”的深度为0, “空表”的深度为 1。
广义表可以是一个递归的表; 递归表的深度是无穷值,长度是有限值。
③ 广义表可以共享;如广义表F可同时为广义表D和C的子表。 ④ 广义表可以是一个递归的表。如广义表B,递归表的深度是无穷值,长度是有限值。 ⑤ 任何一个非空广义表 LS = ( 1, 2, …, n) 均可分解为: 表头 Head(LS) = 1 和 表尾 Tail(LS) = ( 2, …, n)两部分。 例如: D = ( E, F ) = ((a, (b, c)),F ) Head( D ) = E Tail( D ) = ( F ) Head( E ) = a Tail( E ) = ( ( b, c) ) Head( (( b, c)) ) = ( b, c) Tail( (( b, c)) ) = ( )
广义表的存储结构
广义表的遍历
问答题
邻接表与邻接矩阵有什么异同之处?
联系:邻接表中每个链表对应于邻接矩阵中的一行,链表中结点个数等于一行中非零元素的个数。
区别: ① 对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(链接次序与顶点编号无关)。 ② 邻接矩阵的空间复杂度为O(n2),而邻接表的空间复杂度为O(n+e)。
用途:邻接矩阵多用于稠密图的存储(e接近n(n-1)/2);而邻接表多用于稀疏图的存储(e<<n2)