数据结构学习笔记-图

来源:互联网 发布:二手手机交易软件 编辑:程序博客网 时间:2024/04/29 22:04

顶点(vertex):图中的数据元素称为顶点。

(arc):<v,w>表示弧尾为v,弧头为w的一条从v到w的弧。这时的图称为有向图

(edge):(v,w)代替这两个有序对,表示v和w之间的一条边,此时的图称为无向图。

我们用n表示图中顶点数目,用e表示边或弧的数目。对于无向图,e的取值范围为:0~n(n-1)/2。有n(n-1)/2条边的无向图称为完全图,有n(n-1)条弧的有向图称为有向完全图

对于无向图,如果(v,v')存在,则称v和v’是互为邻接点。顶点v的就是与该顶点相关联的边的数目。

对于有向图,如果<v,v'>存在,则称v邻接到顶点v',顶点v'邻接自顶点v。而v的度分为出度入度,以v为尾的弧的个数称为v的出度,以v为头的弧的个数称为v的入度,v的度为出度+入度

无向图中,从顶点v到顶点v’的路径是一个顶点序列,路径的长度是路径上的边或弧的数目。

                   第一个顶点和最后一个顶点相同的路径称为回路,如果无向图中,从顶点v到v'有路径则称v和v’

                  是连通的,如果对于图中任意两个顶点来说都是连通的,则称图是连通图。无向图中的极大连通子

                  图称为连通分量

有向图中,如果对于每一对vi,vj且vi!=vj,从vi到vj和从vj到vi都存在路径,则称为强连通图。有向图中的极大

                  强连通子图称做强连通分量

一个连通图的生成树是一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边。

结论:1.如果一个图有n个顶点和小于n-1条边,则是非连通图。

           2.如果它多于n-1条边,则一定有环。

图的存储结构

        图没有顺序映像,只有链式映像结构。用多重链表表示图是自然的事,即一个由一个数据域和多个指针域组成的结点表示图中一个顶点,数据域存储顶点信息,指针域存储指向其邻接点的指针。

1>数组表示法(邻接矩阵表示法):

两个数组分别存储数据元素(顶点)和数据元素之间的关系(边或弧)信息。存储结构如下:

需要注意的地方:邻接矩阵的主对角线上的元素为0;对于无向图邻接矩阵是关于主对角线对称的;有向图中行表示弧出发的顶点,列表示弧接收的顶点。

2>邻接表(将数组、链表结合使用)

是图的一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点vi的边(对于有向图是以顶点vi为尾的弧)。表结点有3个域,邻接点域(与该点邻接的点在图中的位置,即该点在数组中的位置);链域指示下一条边或弧的结点;数据域存储和边或弧相关的信息,如权值。头结点有2个域,一个数据域,一个指针域(该指针指向链表的第一个结点)。

对于无向图的邻接表,顶点Vi的度恰为第i个链表中的结点个数;对有向图的邻接表结点的出度很容易得到,但是该结点的入度则需要遍历整个邻接表。

对于无向网的每条边只动态生成一个存放权值的存储空间,由两个表结点共同指向。

在邻接表上容易找到任一顶点的第一个邻接点和下一个邻接点,但要判定任意两个顶点(vi和vj)之间是否有边或弧相连,则需搜索第i个或第j个链表,因此不及邻接矩阵方便。

3>十字链表

是有向图的另一种链式存储结构。十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点。

弧结点有5个域:tailvex, headvex, hlink, tlink, info;

tailvex域代表的是该弧的弧尾顶点,存储的值的类型是int型,是弧尾在顶点数组中的下标

headvex域代表的是弧的弧头顶点,存储的值的类型是int型,是弧头在顶点数组中的下标

hlink域指的是与该弧有相同弧头顶点的下一个弧结点,存储的是ArcBox *类型的指针(即下一个弧结点的地址)

tlink域指的是与该弧有相同弧尾顶点的下一个弧结点,存储的是ArcBox *类型的指针。

info域指向该弧的相关信息。

顶点结点(在顶点数组中)有3个域:data,firstin,firstout;

data域代表的是该顶点的信息,(名称)

firstin和firstout为两个链域,存储的是ArcBox *类型的指针,分别指向的是以该顶点为弧头弧尾的第一个弧结点。

图的遍历

定义:从图中的某一点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。这一过程就叫图的遍历

为了避免同一顶点被访问多次,在遍历的过程中需要设一个辅助数组visited[0..n-1],它的初始值置为“假”或者零,一旦访问了顶点vi,便置visited[i]为“真”或者为被访问时的次序号。

遍历图的路径有两种:深度优先搜索(DFS),广度优先搜索(BFS)

深度优先搜索(DFS):很类似于树的先序遍历

从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v

有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

显然这是一个递归的过程,该遍历过程需要用到访问标志数组。

广度优先搜索(BFS):遍历类似按层次遍历的过程。

从图中某个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有的点都被访问到为止。

从上面的描述可以看出,广度优先搜索不仅需要用到访问标志数组,还需要用到队列。

深度优先搜索和广度优先搜索的不同只是在于对顶点的访问顺序不同,而时间复杂度是相同的。

下面给出用邻接表来存储无向图,并对该无向图进行DPS的程序

0 0