图的基本概念和基本操作.ppt
《图的基本概念和基本操作.ppt》由会员分享,可在线阅读,更多相关《图的基本概念和基本操作.ppt(189页珍藏版)》请在三一办公上搜索。
1、第8章 图,8.1 图的基本概念和基本操作 8.2 图的邻接矩阵存储结构 8.3 图的邻接表存储结构 8.4 图的其他存储结构 8.5 最小生成树 8.6 最短路径,8.1 图的基本概念和基本操作,8.1.1 图的基本概念 图(Graph)是由顶点集合及顶点间的关系集合组成的一种数据结构。图G的定义是:G=(V,E)式中:V=x|x某个数据对象 E=(x,y)|x,yV 或 E=x,y|x,yV并且Path(x,y),图81 带自身环的图和多重图(a)带自身环的图;(b)多重图,这样,在图G中,V是顶点的有穷非空集合,E是顶点之间关系的有穷集合,E也叫做边的集合。图有许多复杂结构,本教材只讨论
2、最基本的图,因此,本书讨论的图中不包括图81所示两种形式的图。图81(a)中有从顶点A到自身的边存在,称为带自身环的图;图81(b)中从顶点B到顶点D有两条无向边,称为多重图。,下面我们给出图的基本概念:(1)有向图和无向图:在有向图中,顶点对x,y是有序的,顶点对x,y称为从顶点x到顶点y的一条有向边,因此,x,y与y,x是两条不同的边。有向图中的顶点对x,y用一对尖括号括起来,x是有向边的始点,y是有向边的终点,有向图中的边也称作弧。在无向图中,顶点对(x,y)是无序的,顶点对(x,y)称为与顶点x和顶点y相关联的一条边,这条边没有特定的方向,(x,y)与(y,x)是同一条边。,图8给出了
3、四个图例。其中,图G1和G2是无向图。G1的顶点集合为V(G1)=0,1,2,3,边集合为E(G1)=(0,1),(0,2),(0,3),(1,2),(1,3),(2,3);图G3和G4是有向图,G3的顶点集合为V(G3)=0,1,2,边集合为E(G3)=0,1,1,0,1,2。对于有向边,边的方向用箭头画出,箭头从有向边的始点指向有向边的终点。,图8四个图例(a)G1;(b)G2;(c)G3;(d)G4,(2)完全图:在有n个结点的无向图中,若有n(n-1)/2条边,则称此图为无向完全图。图8的G1就是无向完全图。在有n个结点的有向图中,若有n(n-1)条边,则称此图为有向完全图。图8的G4
4、就是有向完全图。完全图中的顶点个数和边的个数都达到最大值。,(3)邻接顶点:在无向图G1,G2中,若(u,v)是E(G)中的一条边,则称u和v互为邻接顶点,并称边(u,v)依附于顶点u和v。在图8的无向图G1中,顶点0的邻接顶点有顶点1,2和3;在有向图G3,G4中,若u,v是E(G)中的一条边,则称顶点u邻接到顶点v,顶点v邻接自顶点u,并称边u,v与顶点u和顶点v相关联。在图8的有向图G3中,顶点1因边1,2邻接到顶点2。,(4)顶点的度:顶点v的度是与它相关联的边的条数,记作TD(v)。在有向图中,顶点的度等于该顶点的入度和出度之和,即TD(v)=ID(v)+OD(v)。顶点v的入度ID
5、(v)是以v为终点的有向边的条数;顶点v的出度OD(v)是以v为始点的有向边的条数。在图8的有向图G3中,顶点1的入度ID(1)=1,顶点1的出度OD(1)=2,所以,顶点1的度 TD(v)=ID(v)+OD(v)=1+2=3。可以证明,在一个有n个顶点、e条有向边(或无向边)的图中,恒有下列关系式:,(5)路径:在图G=(V,E)中,若从顶点vi出发有一组边使可到达顶点vj,则称顶点vi到顶点vj的顶点序列为从顶点vi到顶点vj的路径。在图8的图G2中,从顶点0到顶点3的路径为0,1,3。(6)权:有些图的边附带有数据信息,这些附带的数据信息称为权。权可以表示实际问题中从一个顶点到另一个顶点
6、的距离、花费的代价、所需的时间,等等。带权的图称作网络。图83就是带权图。其中,图83(a)是一个工程的施工进度图,图8-3(b)是一个交通网络图。,图83 带权图(a)施工进度图;(b)交通网络图,(7)路径长度:对于不带权的图,一条路径的路径长度是指该路径上的边的条数;对于带权的图,一条路径的路径长度是指该路径上各个边权值的总和。在图8的无向图G2中,路径0,1,3的路径长度为2;在图83(a)的有向图中,路径1,3,6,7的路径长度为16,路径1,4,7的路径长度为31。(8)子图:设有图G1=V1,E1和图G2=V2,E2,若V2V1且E2E1,则称图G2是图G1的子图。,(9)连通图
7、和连通分量:在无向图中,若从顶点vi到顶点vj有路径,则称顶点vi和顶点vj是连通的。如果图中任意一对顶点都是连通的,则称该图是连通图。非连通图的极大连通子图称作连通分量。图82的无向图G1和G2都是连通图。(10)强连通图和强连通分量:在有向图中,若对于每一对顶点vi和vj都存在一条从vi到vj和从vj到vi的路径,则称该图是强连通图。非强连通图的极大强连通子图称作强连通分量。图82的有向图G4是强连通图。图82的有向图G3不是强连通图,但G3有一个强连通分量包括顶点0和顶点1,边0,1和边1,0。,(11)生成树:一个连通图的极小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶
8、点和n-1条边。(12)简单路径和回路:若路径上各顶点v1,v2,vm,均互不重复,则称这样的路径为简单路径;若路径上第一个顶点v1与最后一个顶点vm重合,则称这样的路径为回路或环。,8.1.2 图的基本操作 讨论各种类型的图都要用到的图的基本操作。(1)在图中增加一个顶点;(2)如果顶点v1和v2是图中的两个顶点,则在图中插入边(v1,v2);(3)如果顶点v是图中的顶点,则删除图中顶点v和与顶点v相关联的所有边;(4)如果边(v1,v2)是图中的一条边,则删除边(v1,v2);(5)如果顶点v是图中的顶点,则取顶点v的第一个邻接顶点;,(6)如顶点v和顶点w是图中的两个顶点且它们互为邻接顶
9、点,则取得顶点v的w邻接顶点的下一个邻接顶点。(7)按某种规则遍历图。和树的遍历类同,图的遍历也是访问图中的每一个顶点且每个顶点只被访问一次。,8.2 图的邻接矩阵存储结构,8.2.1 邻接矩阵 我们首先定义邻接矩阵。假设图G=(V,E)有n个顶点,即V=v0,v1,vn-1,E可用如下形式的矩阵A描述,对于A中的每一个元素aij,满足:,若(i,j)E或i,jE,否则,由于矩阵A中的元素aij表示了顶点i和顶点j之间边的关系,或者说,A中的元素aij表示了顶点i和其他顶点j(0jn-1)的邻接关系,所以矩阵A称作邻接矩阵。在图的邻接矩阵存储结构中,顶点信息使用一维数组存储,边信息的邻接矩阵使
10、用二维数组存储。图84(a)是一个无向图,图84(b)是对应的邻接矩阵存储结构。其中,V表示了图的顶点集合,A表示了图的邻接矩阵。无向图的邻接矩阵一定是对称矩阵。从无向图的定义和无向图的邻接矩阵定义可知,邻接矩阵中第i行(或第i列)中非零元素的个数等于第i个顶点的度数。又由于邻接矩阵中非零元的数值为1,所以有,图84无向图及其邻接矩阵(a)无向图;(b)邻接矩阵,图85(a)是一个有向图,图85(b)是对应的邻接矩阵存储结构,其中,V表示图的顶点集合,A表示图的邻接矩阵。有向图的邻接矩阵一般是非对称矩阵。从有向图的定义和有向图的邻接矩阵定义可知,有向图的邻接矩阵中第i行中非零元素的个数等于第i
11、个顶点的出度,有向图的邻接矩阵中第i列中非零元素的个数等于第i个顶点的入度,又由于邻接矩阵中非零元素的数值为1,所以有:,图85 有向图及其邻接矩阵(a)有向图;(b)邻接矩阵,对于网(或称带权图),邻接矩阵A的定义为:,ij且(i,j)E或i,jE,否则但ij,否则但i=j,其中,wij0,wij是边(i,j)或弧,i,j的权值,权值wij表示了从顶点i到顶点j的代价或称费用。当i=j时,邻接矩阵中的元素aij=0可理解为从一个顶点到自己顶点没有代价,这也完全和实际应用中的问题模型相符。有种特殊的网允许wij为负值,本书讨论的网不包括此种网。,图86(a)是一个带权图,图86(b)是对应的邻
12、接矩阵存储结构。其中,V表示图的顶点集合,A表示图的邻接矩阵。对于带权图,邻接矩阵第i行中所有0aij的元素个数等于第i个顶点的出度,邻接矩阵第j列中所有0aij的元素个数等于第j个顶点的出度。,图86 带权图及其邻接矩阵(a)带权图;(b)邻接矩阵,8.2.2 邻接矩阵表示的图类 对于上述的无向图、有向图和带权图三种类型的图,其图类实现方法基本类同,如有向图中的弧a,b和弧b,a就等同于无向图中的边(a,b),把不带权图中的边信息均定为1,不带权图就变成了带权图。因此,在上述三种类型的图中,带权图最有代表性。下面我们就以带权图为例讨论邻接矩阵表示的图类。,1.图类的定义 在邻接矩阵表示的图中
13、,顶点信息用一个一维数组表示,边(或称弧)信息用一个二维数组表示。在这里,顶点信息我们用第3章讨论的线性表表示,因此我们可以利用线性表实现的功能和提供的共有成员函数方便地完成顶点的插入、删除等操作。我们在第3章设计的线性表类是使用抽象数据类型Datatype来定义要操作的数据对象的,因此这里要在主函数使用图类之前定义抽象数据类型Datatype为图的顶点信息数据类型,我们的测试例子中定义图的顶点信息数据类型(Vert)为char类型。,大多数情况下带权图的边信息只包含边的权值,作为教科书,我们主要注重基本原理和方法的讨论,因此我们这里设计的图类的边信息只包含边的权。注意,由于我们利用线性表来保
14、存顶点信息,所以关于顶点信息的当前个数、是否表已满无法再继续插入等均由线性表来维护,这里无需再考虑,这也正是面向对象程序设计最主要的优点之一。,include SeqList.hinclude SeqQueue.hconst int MaxVertices=10;const int MaxWeight=10000;class AdjMWGraphprivate:SeqList Vertices;/顶点信息的线性表,int EdgeMaxVerticesMaxVertices;/边的权信息的矩阵int numOfEdges;/当前的边数public:AdjMWGraph(const int sz
15、=MaxVertices);/构造函数int GraphEmpty()const/图空否return Vertices.ListEmpty();int NumOfVertices(void)/取当前顶点个数return Vertices.ListSize();,int Num Of Edges(void)/取当前边个数return numOfEdges;VerT Get Value(const int i);/取顶点i的值int Get Weight(const int v1,const int v2);/取弧v1,v2的权/插入顶点vertexvoid InsertVertex(const
16、VerT,/删除弧v1,v2void DeleteEdge(const int v1,const int v2);/取顶点v的第一条邻接边,取到返回该邻接边的邻接顶点下标;否则返回-1int GetFirstNeighbor(const int v);/取顶点v1的邻接边的下一条邻接边,/若下一条邻接边存在,则返回该邻接边的邻接顶点下标;否则返回-1int GetNextNeighbor(const int v1,const int v2);/对连通图从顶点v开始用visit()深度优先搜索访问,visited为访问标记void DepthFirstSearch(const int v,int
17、 visited,void visit(VerT item);/对连通图从顶点v开始用visit()广度优先搜索访问,visited为访问标记void BroadFirstSearch(const int v,int visited,void visit(VerT item);/对非连通图用visit()进行深度优先搜索访问void DepthFirstSearch(void visit(VerT item);/对非连通图用visit()进行广度优先搜索访问void BroadFirstSearch(void visit(VerT item);,2.成员函数的实现 AdjMWGraph:Adj
18、MWGraph(const int sz)/构造函数for(int i=0;i sz;i+)for(int j=0;j sz;j+)if(i=j)Edgeij=0;else Edgeij=MaxWeight;/MaxWeight表示无穷大numOfEdges=0;/当前边个数初始为0,VerT AdjMWGraph:GetValue(const int i)/取顶点i的值if(i Vertices.ListSize()cerr 参数i越界出错!endl;exit(1);/使用线性表的GetData(i)成员函数返回顶点i的值return Vertices.GetData(i);,int Adj
19、MWGraph:GetWeight(const int v1,const int v2)/取弧v1,v2的权if(v1 Vertices.ListSize()|v2 Vertices.ListSize()cerr 参数v1或v2越界出错!endl;exit(1);,return Edgev1v2;/返回弧v1,v2的权void AdjMWGraph:InsertVertex(const VerT,void AdjMWGraph:InsertEdge(const int v1,const int v2,int weight)/插入弧v1,v2,权为weightif(v1 Vertices.Lis
20、tSize()|v2 Vertices.ListSize()cerr 参数v1或v2越界出错!endl;exit(1);Edgev1v2=weight;/插入权为weight的边,numOfEdges+;/边个数加1void AdjMWGraph:DeleteVertex(const int v)/删除顶点v和与顶点v 相关的所有边/删除与顶点v相关的所有边for(int i=0;i Vertices.ListSize();i+)for(int j=0;j Vertices.ListSize();j+),if(i=v|j=v)/删除顶点v,void AdjMWGraph:DeleteEdge(
21、const int v1,const int v2)/删除弧,v1,v2if(v1 Vertices.ListSize()|v2 Vertices.ListSize()|v1=v2)cerr 参数v1或v2出错!endl;exit(1);,Edgev1v2=Max Weight;/把该边的权值置为无穷Num Of Edges-;/边个数减1,8.2.3 邻接矩阵图类的深度优先搜索遍历 和树的遍历操作类同,图的遍历操作也是图问题中最基本和最重要的操作。图的遍历操作的定义是访问图中的每一个顶点且每个顶点只被访问一次。图的遍历操作方法有两种:一种是深度优先搜索遍历,另一种是广度优先搜索遍历。图的深度
22、优先搜索遍历类同于树的先根遍历,图的广度优先搜索遍历类同于树的层序遍历。,图的遍历算法设计需要考虑三个问题:(1)图的特点是没有首尾之分,所以算法的参数要指定访问的第一个顶点;(2)对图的遍历路径有可能构成一个回路,从而造成死循环,所以算法设计要考虑遍历路径可能的回路问题;(3)一个顶点可能和若干个顶点都是相邻顶点,要使一个顶点的所有相邻顶点按照某种次序被访问。,我们首先考虑第(3)个问题的解决方法。为解决图的遍历操作的这个问题,我们在图的成员函数中设计了GetFirstNeighbor(v)成员函数和GetNextNeighbor(v1,v2)成员函数。GetFirstNeighbor(v)
23、找顶点v的第一条邻接边,若存在,则返回该邻接边的邻接顶点下标;否则返回-1。GetNextNeighbor(v1,v2)找顶点v1的v1,v2邻接边的下一条邻接边,若下一条邻接边存在,则返回该邻接边的邻接顶点下标;否则返回-1。,有了这两个成员函数,我们就可以从顶点v1首先找到第一条邻接边v1,v2,再从顶点v1的v1,v2邻接边找顶点v1的v1,v2邻接边后的下一条邻接边,从而可以找到顶点v1的所有邻接边。这两个成员函数的算法设计如下:int AdjMWGraph:GetFirstNeighbor(const int v)/找顶点v的第一条邻接边,若存在则返回该邻接边的邻接顶点下标;否则返回
24、-1 if(v Vertices.ListSize(),cerr 0/不存在,则返回-1int AdjMWGraph:GetNextNeighbor(const int v1,const int v2)/找顶点v1的v1,v2邻接边的下一条邻接边,,/若下一条邻接边存在,则返回该邻接边的邻接顶点下标;否则返回-1if(v1 Vertices.ListSize()|v2 Vertices.ListSize()cerr 参数v1或v2越界出错!endl;exit(1);,/使col=v2+1,因此寻找的是顶点v1的v1,v2邻接边的下一条邻接边for(int col=v2+1;col 0/不存在,
25、则返回-1,对于连通图,从初始顶点出发一定存在路径和图中的所有其他顶点相连,所以对于连通图从初始顶点出发一定可以遍历该图。图的深度优先遍历算法是遍历时深度优先的算法,即在图的所有邻接顶点中每次都在访问完当前顶点后首先访问当前顶点的第一个邻接顶点,这样的算法是一个递归算法。连通图的深度优先搜索遍历算法思想是:(1)访问初始顶点v并标记顶点v为已访问;(2)查找顶点v的第一个邻接顶点w;,(3)若顶点v的邻接顶点w存在,则继续执行,否则算法结束;(4)若顶点w尚未被访问,则访问顶点w并标记顶点w为已访问;(5)查找顶点v的w邻接顶点后的下一个邻接顶点w,转到步骤(3)。,void AdjMWGra
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基本概念 基本 操作

链接地址:https://www.31ppt.com/p-5097546.html