图的一些性质,解决一些图的算法问题,首先要看入手点
A 图的存储结构
带权的邻接矩阵存储结构
template<class T>
struct Graph (图的定义 数据)
{
T vertex[MaxSize];// 存放图中顶点的数组
int arc[MaxSize][MaxSize];// 存放图中边的数组
int vertexNum, arcNum;// 图中顶点数和边数
};
G(V,E)
由此展开的各种算法问题研究:
一。最短路径问题:
①在非网图中,最短路径是指两顶点之间经历的边数最少的路径。
②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径。
③单源点最短路径问题
问题描述:给定带权有向图G=(V, E)和源点v∈V,求从v到G中其余各顶点的最短路径。
应用实例——计算机网络传输的问题:怎样找到一种最经济的方式,从一台计算机向网上所有其它计算机发送一条消息。
④每一对顶点之间的最短路径
问题描述:给定带权有向图G=(V, E),对任意顶点vi,vj∈V(i≠j),求顶点vi到顶点vj的最短路径。
解决办法1:每次以一个顶点为源点,调用Dijkstra算法n次。显然,时间复杂度为O(n3)。
解决办法2:弗洛伊德提出的求每一对顶点之间的最短路径算法——Floyd算法,其时间复杂度也是O(n3),但形式上要简单些。
Dijkstra算法
Dijkstra算法求某一个源点到其余各顶点时间复杂度是O(n^2),但如果采用此算法,找从某一源点到某一特定终点的最短路径,复杂度仍为O(n^2)。
思想:
设置一个集合S存放已经找到的最短路径的顶点,S的初始状态只包含源点v,对 Vi ∈ V-S
直到集合V中全部顶点加入到集合S中。
设计数据结构 :
1、图的存储结构:带权的邻接矩阵存储结构 。
2、数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长度。初态为:若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
3、数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
4、数组s[n]:存放源点和已经生成的终点,其初态为只有一个源点v。
Floyd算法
解决任意两点间的最短路径的一种算法,可以正确处理有向图或有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包。
二、最小生成树
在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树。
问题一 对图的所有边按照权值大小进行排序。
问题二 将边添加到最小生成树中时,怎么样判断是否形成了回路。
问题一很好解决,采用排序算法进行排序即可。
问题二,处理方式是:记录顶点在"最小生成树"中的终点,顶点的终点是"在最小生成树中与它连通的最大顶点"(关于这一点,后面会通过图片给出说明)。然后每次需要将一条边添加到最小生存树时,判断该边的两个顶点的终点是否重合,重合的话则会构成回路。
Kruskal)算法
采用贪心算法的思想,运行时间为O(nlogn)
思想:
设置一个集合S存放已经找到的最短路径的顶点,S的初始状态只包含源点v,对 Vi ∈ V-S
直到集合V中全部顶点加入到集合S中。
设计数据结构 :
图的存储结构:邻接矩阵 或者是 邻接表
Prim算法
此算法采用贪心算法的思想,运行时间为O( n^2 )。
基本步骤:
设R是有n个定点的对称连通关系。
1)选取R的一个定点v1,设V = {v1}, E={}。
2)选取与vj ∈ V邻接的V的最近邻元vi, 并且边(vi, vj)不与E中元素形成回路。添加vi到V中,添加(vi, vj)到E中。
重复2),知道|E|=n - 1,于是V包含R的所有n个定点,E包含R的最小生成树。