第六章图
1、图的一些相关定义
2、图的存储结构
(1)邻接矩阵法:
所谓邻接矩阵存储,是指用一个一维数组存储图中顶点的信息,用一个二维数组存储图中边的信息,存储顶点之间的邻接关系的二维数组称为邻接矩阵。(适合稠密图)
(2)邻接表法:
当一个图为稀疏矩阵时,使用邻接矩阵法显然要浪费大量的存储空间,而图的邻接表法结合了顺序存储和链式存储方法,大大减少了这种不必要的浪费。
(3)十字链表法:
十字链表法是有向图的一种链式存储结构。在十字链表中,对应于有向图中的每条弧有一个结点,对应于每个顶点也有一个结点。
(4)邻接多重表:
邻接多重表是无向图的另一种链式存储结构。
在邻接表中,容易求得顶点和边的各种信息,但在邻接表中求两个顶点之间是否存在边而对边执行删除等操作时,需要分别在两个顶点的边表中遍历,效率较低。与十字链表类似,在邻接多重表中,每条边用一个结点表示,每个顶点也用一个结点表示。
3、图的遍历
图的遍历是指从图中的某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次。注意到树是一种特殊的图,所以树的遍历实际上也可视为一种特殊的图的遍历。图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。图的遍历比树的遍历要复杂的多,因为图的任一顶点都可能和其余的顶点相邻接,所以在访问某个顶点后,可能沿着某条路径搜索又回到该顶点上。为避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点,为此可以设一个辅助数组visited[]来标记顶点是否被访问过。图的遍历算法主要有两种:广度优先搜索和深度优先搜索。
(1)广度优先搜索
类似于二叉树的层次遍历算法。基本思想:首先访问起始顶点V,接着由V出发,一次访问V的各个未访问过的邻接顶点W1,W2,…Wn,然后依次访问W1,W2…Wn的所有未被访问过的邻接顶点;再从这些访问过的顶点出发,访问它们所有未被访问过的邻接顶点,直至图中所有顶点都被访问过为止。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为初始点,重复上述过程。Dijkstra源最短路径算法和Prim最小生成树算法也应用了类似的思想。
(2)深度优先搜索
它的基本思想如下:首先访问图中某一起始顶点V,然后由V出发,访问与V邻接且未被访问的任一顶点W1,再访问与W1邻接且未被访问的任一顶点W2…重复上述过程。当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接顶点未被访问过,则从该点开始继续上述搜索过程,直至图中所有顶点均被访问过为止。
4、最小生成树和最短路径
**普利姆算法:**用来求最小生成树。从一个连通图中从某一顶点出发,选择与它关联的最小权值的边,将其顶点加入到顶点集S中,此后就从一个顶点在S集中,另一个顶点不在S集中的左右顶点中选择出权值最小的边,把对应顶点加入到S集中,直到所有的顶点都加入到S集中为止。
**克鲁斯卡尔算法:**用来求最小生成树,其基本思想为:设有一个有N个顶点的连通网中,选出权值最小的边且该边的两个端点不在一个连通分支中,则把该边加入到树中,否则就再从新选择一条权值最小的边,直到所有的顶点都在一个连通分支中为止。
**迪杰斯特拉算法:**迪杰斯特拉算法是经典的单源最短路径算法,用于求某一顶点到其他顶点的最短路径,它的特点是以起始点为中心层层向外扩展,直到扩展的终点为止,迪杰斯特拉算法要求边的权值不能为负权。
**弗洛伊德算法:**弗洛伊德算法是经典的求任一顶点之间的最短路径,其边的权值可为负权,该算法的时间复杂度为O(n3),空间复杂度为O(n2)。
5、关键路径