图是一种比线性表和树更为复杂的数据结构,在线性表中,数据元素之间只有线性关系,每个数据元素只有一个直接前驱和直接后继;在树形结构中,数据元素之间有明显的层次关系,并且每一层的数据元素可能与下一层中多个元素有关系,但只能和上一层的一个结点有关系;而在图中,结点之间的关系是任意的,图中任意两个元素都有可能相关。
图:一个图G = (V,R)由顶点V(G)和边R(G)组成,其中V(G)是顶点的非空有限集,R(G)是边的非空有限集。每一条边就是一个点对(v,w),如果边是有方向的,为<v,w>则称为有向图;如果边是没有方向的,则称为无向图。
有向完全图:所有顶点之间都有边的有向图,n个顶点有n*(n-1)个边
无向完全图:所有顶点之间都有边的无向图,n个顶点有n*(n-1)/2个边
权:与图的边相关的数
网:带权的图
顶点的度:无向图中,顶点的度为与每个顶点相连的边数;有向图中,顶点的度分为入度和出度,入度是以该顶点为终点的边的个数,出度是以该点为始点的边的个数
路径:依次遍历顶点序列之间的边所形成的轨迹,路径是顶点的序列
路径长度:沿路径的边的个数,有权就是所有边的权和
回路:第一个顶点和最后一个顶点相同的路径
简单路径:路径序列中顶点不重复出现的路径
简单回路:除了第一个顶点和最后一个顶点,其余顶点不重复的回路
连通:两个顶点之间存在一条路径,则这两个顶点是连通的
连通图:图中任意两个顶点都是连通的图
强连通图:在有向图中,两个顶点a,b,从a到b和b到a都有路径
图的存储结构有两种,邻接矩阵和邻接表。
邻接矩阵:表示图的一种简单的办法是使用一个二维数组,称为邻接矩阵表示法。对于每条边(u,v),我们设置A[u][v]=1,证明二者之间有边,否则则设为0;如果边有权,则可以设置该值等于该权,对于不存在的边,使用∞或者0表示。这种表示方法虽然简单,但是空间需求比较大是O(n2),如果图的边不多的情况(稀疏),代价太大了。假如有三个顶点,就要一个3*3的二维数组,但是假如只有两条边,就要浪费九个空间。
邻接表:邻接矩阵适合于比较稠密的图,对于稀疏的图,使用邻接表表示会更好一些。邻接表的结构像我们之前学过的散列表,由一个头单元数组来存储所有顶点,在数组后面通过链表表示与该顶点存在边的顶点。邻接表是表示图的标准方法。这里提一下,无向图和有向图都可以使用邻接表,但是无向图的使用空间基本是双倍的,因为一个边需要在两个点里都有体现,而有向图是有方向的,一条边只在边的起始顶点表示就可以了。
程序参考散列表那节的程序