版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章图教学要求相关知识点图的常用术语:有向图、无向图、完全图、有向完全图、稀疏图、稠密图、网、邻接点、路径、简单路径、回路或环、简单回路、连通、连通图、强连通图、生成树图的邻接矩阵存储表示图的邻接表存储表示图的深度优先遍历(Depth-FirstSearch,DFS)图的广度优先遍历(Breadth-FirstSearch,BFS)最小生成树拓扑排序和关键路径最短路径教学要求学习重点图的存储与操作图的遍历、最小生成树、最短路径算法目录图的存储与操作图的遍历图与最小生成树3图的定义和基本术语124最短路径5AOV网与拓扑排序AOE网与关键路径本章小结7686.1图的定义和基本术语6.1图的定义和基本术语图的定义及基本术语1.图的定义在图中的数据元素通常称为顶点,图G(Graph)是由顶点集合(vertex)及顶点之间的关系集合(称为边或弧)组成的一种数据结构。记为G=(V,E)。2.图的基本术语(1)无向边如果顶点vi和vj间的边没有方向,则称该边为无向边(Edge)。用无序偶对表示:(vi,vj)。6.1图的定义和基本术语(2)有向边(弧)如果顶点vi和vj间的边有方向,则称该边为有向边(或称为弧Arc)。用有序偶对表示:<vi,vj>。(3)无向图在一个图G中,任意两个顶点构成的偶对(vi,vj)∈E都是无序的,即两点相连形成的边都是没有方向的,则称该图为无向图(Undigraph)。图6.1(a)所示是一个无向图G1。图6.1(a)无向图G1
6.1图的定义和基本术语(4)有向图在一个图G中,任意两个顶点构成的偶对(vi,vj)∈E都是有序的,即两点相连形成的边都是有方向的,则称该图为有向图(Digraph)。如图6.1(b)所示是一个有向图G2,在该图中,G2=(V2,E2),V2={v1,v2,v3},E2={<v1,v2>,<v2,v1>,<v2,v3>,<v1,v3>}。图6.1(b)有向图G26.1图的定义和基本术语(5)弧头、弧尾在无向图中,任意两个顶点之间的连线称为边,并且不区分首尾;在有向图中,任意两个顶点之间的连线称为弧,并且,有向图的弧需区分弧头和弧尾。例如:将顶点vi和vj之间的连线记为有序偶对<vi,vj>,其中顶点vi称为初始点(弧尾Tail),即弧的射出端,就是不带箭头的一端。顶点vj称为终端点(或弧头Head),即弧的射入端,就是带着箭头的一端。6.1图的定义和基本术语(6)权、网在边或者弧上的数据信息称为边的权(Weight)。权值可以表示从一个顶点到另一个顶点的距离、时间或者价格等。带权的图称为网(Network)。
图6.2(a)无向网G3图6.2(b)有向网G4。6.1图的定义和基本术语(7)完全图如果无向图中任意两个顶点间都存在边,则称之为无向完全图(CompletedGraph)。在一个含有n个顶点的无向完全图中,边数为n(n-1)/2条。如果有向图中任意两个顶点间都存在方向互为相反的两条弧,则称之为有向完全图。在一个含有n个顶点的有向完全图中,边数为n(n-1)条。(8)稠密图、稀疏图当一个图接近完全图时,称之为稠密图(DenseGraph);相反地,当一个图中含有较少的边或弧时,则称之为稀疏图(SparseGraph)。6.1图的定义和基本术语(9)子图若有两个图G1和G2,其中,G1=(V1,E1),G2=(V2,E2),且满足如下条件:V2⊆V1,E2⊆E1即V2为V1的子集,E2为E1的子集,则称图G2为图G1的子图。6.1图的定义和基本术语(10)邻接点和度对于无向图,假若顶点v和顶点w之间存在一条边,则称顶点v和w互为邻接点;和顶点v关联的边的数目定义为v的度。记为ID(v)。无向图不区分入度和出度。对于有向图,由于弧有方向性,则有入度和出度之分。顶点的出度(OutDegree)是以顶点v为弧尾的弧的数目,记为OD(v);顶点的入度(InDegree)是以顶点v为弧头的弧的数目,记为ID(v);顶点的度记为TD(v),有TD(v)=OD(v)+ID(v)。6.1图的定义和基本术语(11)路径、路径长度顶点vi到顶点vj的路径(Path)是指从顶点vi到顶点vj之间所经历的顶点序列vi,vi,1…vi,m,vj,其中(vi,vi,1)(vi,m,vj)和(vi,j,vi,j+1)∈E都是图中的边(1≤j≤m-1)。路径的长度是路径上的边或弧的数目。(12)简单路径、回路、简单回路顶点序列中顶点不重复出现的路径,称为简单路径;若顶点序列中第一个顶点和最后一个顶点相同,则称该路径为回路或环(Cycle);若顶点序列中除第一个顶点和最后一个顶点相同外,其余顶点不重复,则称该回路为简单回路或者简单环。6.1图的定义和基本术语(13)连通图、连通分量无向图G中,如果从顶点vi到顶点vj有路径,则称顶点vi和vj是连通的。如果对于图中任意两个顶点vi、vj∈V,vi和vj都是连通的,则称图G为连通图(ConnectedGraph)。在无向图中,在满足连通条件时,尽可能多地包含原图中的顶点和这些顶点之间的边的连通子图称为该图的连通分量(ConnectedComponent);连通图的连通分量是它本身,非连通图的连通分量可能为多个。6.1图的定义和基本术语例如:图6.3中的G5就是一个连通图。而G6就是非连通图,但有2个连通分量,如图6.4所示。6.3连通图G5图6.4非连通图G6及两个连通分量6.1图的定义和基本术语(14)强连通图、强连通分量有向图G中,如果从vi到vj有路径,则称顶点vi和顶点vj是连通的;若图中任意两个顶点之间都存在两条互为反方向的路径,即从vi到vj及从vj到vi都有路径,则称此有向图为强连通图。有向图中的极大连通子图称作该有向图的强连通分量。6.1图的定义和基本术语例如,图6.5中的G7就是一个强连通图。而G8就是非强连通图,但有2个强连通分量,如图6.6所示。图6.6非强连通图G8及两个连通分量图6.5强连通图G76.1图的定义和基本术语(15)生成树连通图G的生成树,是包含G的全部n个顶点的一个极小连通子图,该极小连通子图有(n-1)条边。如图6.7所示,是连通图G5的生成树。如果在一棵生成树上添加一条边,必定构成一个环,因为这条边的出现使得它依附的那两个顶点之间有了第二条路径。一棵有n个顶点的生成树有且仅有(n-1)条边。如果一个图有n个顶点和小于(n-1)条边,则是非连通图。如果它多于(n-1)条边,则一定有环。但需要大家注意的是,有(n-1)条边的图不一定是生成树。6.1图的定义和基本术语(16)生成森林如果一个有向图有且仅有一个顶点的入度为0,其他顶点的入度均为1,则这个图是一棵有向树。当一个有向图有多个顶点的入度为0时,它的生成森林则由多棵有向树构成。这个生成森林含有图中全部的顶点和相应的弧。如图6.8所示是有向图G9及其生成森林。6.1图的定义和基本术语连通图G5及生成树有向图G9及生成森林6.2图的存储与操作6.2图的存储与操作邻接矩阵邻接矩阵(AdjacencyMatrix)是用两个数组来表示图,一个数组是一维数组,存储图中顶点的信息,另一个数组是二维数组,即矩阵,存储顶点之间相邻的信息,也就是边(或弧)的信息。6.2图的存储与操作1.图的邻接矩阵存储法无向图G5的邻接矩阵6.2图的存储与操作1.图的邻接矩阵存储法有向图G9的邻接矩阵6.2图的存储与操作2.网的邻接矩阵存储法无向网的邻接矩阵6.2图的存储与操作2.网的邻接矩阵存储法有向网的邻接矩阵6.2图的存储与操作3.邻接矩阵表示法的特点(1)因为无向图的邻接矩阵具有对称性,一定是一个对称矩阵,所以可以采取压缩存储的方式只存储矩阵的上三角(或下三角)矩阵元素。(2)无向图(网)的邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的度TD(vi)。(3)有向图(网)的邻接矩阵的第i行非零元素(或非∞元素)的个数正好是第i个顶点的出度OD(vi)。(4)有向图(网)的邻接矩阵的第i列非零元素(或非∞元素)的个数正好是第i个顶点的入度ID(vi)。6.2图的存储与操作4.邻接矩阵表示法的优缺点用邻接矩阵方法存储图,很容易确定图中任意两个顶点之间是否有边相连(邻接),但要确定图中有多少条边,则必须按行、按列对每个元素进行检测,所花费的时间代价很大,同时,邻接矩阵存储空间为O(n2),所以适用于稠密图。6.2图的存储与操作5.图的邻接矩阵存储定义/*图的邻接矩阵存储*/#defineMAXSIZE10typedefcharElemType;/*定义顶点数据类型*/typedefstruct{ElemTypeV[MAXSIZE];/*顶点信息*/
intarcs[MAXSIZE][MAXSIZE];//邻接矩阵
inte;/*边数*/
intn;/*顶点数*/}Graph;/*图的邻接矩阵数据类型*/6.2图的存储与操作6.邻接矩阵操作(1)在图中查找顶点在图G中查找顶点v,找到返回其在顶点数组中的索引号;若不存在,返回-1intLocateVex(GraphG,ElemTypev){inti;
for(i=0;i<G.n;i++)
if(G.V[i]==v)returni;
return-1;}6.2图的存储与操作(2)在屏幕上显示图G的邻接矩阵表示算法6.2在屏幕上显示图G的邻接矩阵表示voidDisplayAdjMatrix(GraphG){inti,j;
printf("图的邻接矩阵表示:\n");
for(i=0;i<G.n;i++)
{for(j=0;j<G.n;j++) printf("%3d",G.arcs[i][j]);
printf("\n");
}}6.2图的存储与操作(3)无向图/无向网/有向图/有向网的邻接矩阵的建立算法6.3创建无向图/无向网/有向图/有向网的邻接矩阵voidCreateUndirectedGraphAdj(Graph*pg){
inti,j,k;
ElemTypev1,v2;
for(k=0;k<pg->e;k++)/*边数e*/
{scanf("%c%c",&v1,&v2);/*输入一条边的两个端点(图)*/
scanf("%c%c%d",&v1,&v2,&w);/*输入一条边的两个顶点及边的权(网)*/6.2图的存储与操作/*确定两个顶点在图G中的位置*/
i=LocateVex(*pg,v1);j=LocateVex(*pg,v2);/*创建邻接矩阵*/if(i>=0&&j>=0){pg->arcs[i][j]=1;pg->arcs[j][i]=1;/*创建无向图的邻接矩阵*/
pg->arcs[i][j]=w;pg->arcs[j][i]=w;/*创建无向网的邻接矩阵*/
pg->arcs[i][j]=1;/*创建有向图的邻接矩阵*/
pg->arcs[i][j]=w;/*创建有向网的邻接矩阵*/}
}}6.2图的存储与操作邻接表1.图的邻接表存储法邻接表(AdjacencyList)是图的一种顺序存储与链式存储结合的存储方法;对于图G中的每个顶点Vi,将所有邻接于Vi的顶点Vj链成一个单链表,这个单链表就称为顶点Vi的邻接表;再将所有顶点的邻接表表头放到数组中。6.2图的存储与操作在邻接表表示中,包括两种结点结构。
(1)头节点:由2个域构成。顶点域vex标记顶点vi的信息,链域(firstarc)标记第一个邻接节点。
(2)表节点:由3个域构成,邻接点域(adjvex)标记与顶点vi邻接的点在图中的位置,链域(nextarc)标记下一个与vi邻接的节点,数据域data标记和边(或弧)的相关信息,例如权值等。vexfirstarcadjvexnextarcdata图6.11邻接表的节点结构6.2图的存储与操作2.图的逆邻接表存储法有向图的邻接表不方便查找以vi为弧头的节点数逆邻接表为每一个顶点建立一个以vi为弧头的表。无向图G1的邻接表(a)无向图G1的邻接表仅以顶点编号作为信息输入,时间复杂度为O(n+e)。6.2图的存储与操作2.图的逆邻接表存储法有向图G2的邻接表和逆邻接表(b)有向图G2的邻接表(c)有向图G2的逆邻接表仅以顶点编号作为信息输入,时间复杂度为O(n+e)。6.2图的存储与操作3.无向图的邻接表存储法的特点(1)第i个链表中结点的数目为第i个顶点的度。(2)所有链表中结点的数目的一半为图中边的数目。(3)占用的存储单元数目为n+2e。(n为顶点数,e为边数)
4.有向图的邻接表存储法的性质(1)邻接表中,第i个链表中结点的数目为顶点i的出度。逆邻接表中,第i个链表中结点的数目为顶点i的入度。(2)所有链表中结点的数目为图中弧的数目。(3)占用的存储单元数为n+e。(n为顶点数,e为弧数)6.2图的存储与操作5.邻接表存储法的优缺点在邻接表中可以快速找到某一顶点的邻接点,但是要确定任意两个顶点(vi和vj)间是否有边(或弧),就必须搜索第i个或者第j个链表,在这个方面远不及邻接矩阵快捷。6.2图的存储与操作6.图的邻接表存储定义#defineMAXSIZE10typedefcharElemType;/*定义顶点类型为char*//*边节点的类型定义*/typedefstructArcNode{intadjVex;
structArcNode*nextArc;
intweight;}ArcNode;6.2图的存储与操作/*顶点节点的类型定义*/typedefstructVNode{ElemTypedata;
ArcNode*firstArc;}VNode;/*图的邻接表数据类型*/typedefstruct{VNodeadjList[MAXSIZE];
intn,e;/*图的顶点数和弧数*/}ALGraph;6.2图的存储与操作7.邻接表操作(1)在图G中查找顶点在图G中查找顶点v,找到后返回其在顶点数组中的索引号;若不存在,返回-1intLocateVex(ALGraphG,ElemTypev){inti;
for(i=0;i<G.n;i++)
if(G.adjList[i].data==v)returni;
return-1;}6.2图的存储与操作(2)无向图的邻接表/有向图的邻接表/逆邻接表的建立voidCreateUndirectedGraphLink(ALGraph*pg){inti,j,k;
ElemTypev1,v2;
ArcNode*s;
for(i=0;i<=pg->n;i++) /*n为顶点数*/
{scanf("%c",&pg->adjList[i].data); /*构造顶点信息*/
pg->adjList[i].firstArc=NULL;}
6.2图的存储与操作
for(k=0;k<pg->e;k++) /*e为边数*/
{scanf("%c%c",&v1,&v2);/*确定两个顶点在图G中的位置*/
i=LocateVex(*pg,v1);j=LocateVex(*pg,v2);
if(i>=0&&j>=0)
{
/*创建无向图的邻接表*/
6.2图的存储与操作
s=(ArcNode*)malloc(sizeof(ArcNode));s->adjVex=j;s->nextArc=pg->adjList[i].firstArc;pg->adjList[i].firstArc=s;//头插法s=(ArcNode*)malloc(sizeof(ArcNode));s->adjVex=i;
s->nextArc=pg->adjList[j].firstArc;pg->adjList[j].firstArc=s;//头插法6.2图的存储与操作
/*创建有向图的邻接表*/
s=(ArcNode*)malloc(sizeof(ArcNode));s->adjVex=j;
s->nextArc=pg->adjList[i].firstArc;pg->adjList[i].firstArc=s;//头插法6.2图的存储与操作
/*创建有向图的逆邻接表*/
s=(ArcNode*)malloc(sizeof(ArcNode));s->adjVex=i;
s->nextArc=pg->adjList[j].firstArc;pg->adjList[j].firstArc=s;//头插法
}}}6.2图的存储与操作(3)在屏幕上显示图G的邻接表表示voidDisplayAdjList(ALGraphG){inti;ArcNode*p;printf("图的邻接表表示:");
for(i=0;i<G.n;i++)
{printf("\n%4c",G.adjList[i].data);
p=G.adjList[i].firstArc;
while(p!=NULL){printf("->%d",p->adjVex);
p=p->nextArc;}
}
printf("\n");}6.3图的遍历6.3图的遍历图的遍历:从图中的任意顶点出发,访问其余顶点,并且保证所有顶点都被访问且只被访问一次,称此过程为图的遍历(TraversingGraph)。判断图的连通性、拓扑排序和求关键路径都以图的遍历为基础。图的遍历过程中应该注意以下问题:(1)如何选取起始节点。在无向图中,我们可以任意选取起始节点。在有向图中,我们应当尽量选取入度为0的节点作为起始节点。(2)当遍历的图是非连通图时,从一个节点出发只能访问它所在的连通分量上的所有节点,并不能访问图的所有节点。遍历还需考虑不同连通分量的起始节点的选取问题。6.3图的遍历(3)图中的一个节点可能和多个节点相邻接,我们如何选取下一个邻接点。(4)无向图和有向图中都有可能存在回路,那么在一个节点被访问之后有可能因为回路的存在而再次被访问,我们如何避免一个节点被多次访问。6.3图的遍历深度优先遍历算法1.图的深度优先(DFS)遍历深度优先遍历(depth-firstsearch,DFS)类似于树的先根遍历,是树的先根遍历的推广。假设给定图G的初态是所有顶点均未曾访问过,在G中任选顶点V为出发点(源点),则深度优先搜索遍历可定义为:(1)首先访问出发点V;(2)然后依次从V出发搜索V的每个邻接点W,若W未曾访问过,则以W为新的出发点继续进行深度优先搜索遍历,直至图中所有和源点V有路径相通的顶点(也称为从源点可达的顶点)均已被访问为止;6.3图的遍历(3)若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。这两种深度优先搜索遍历序列为:v1v2v5v4v8v3v7v6v1v2v5v4v8v3v6v7从顶点V1出发的深度优先搜索遍历序列可能有多种,这里只给出其中的两种,其它的可类似分析。6.3图的遍历显然,图的深度优先遍历是一个递归的过程。可以定义一个访问标记数组visited[0…n-1],初始值均为false,一旦某个节点被访问,立即对其相应分量置true,由此可以区别图中节点是否被访问过,并最终遍历所有节点,同时避免了节点的重复访问。6.3图的遍历2.图的深度优先遍历操作算法6.7从图的某一节点出发进行深度优先搜索voidDFSTraverse(GraphG){intv;for(v=0;v<G.n;v++)visited[v]=0;/*初始化标识数组*/for(v=0;v<G.n;v++)/*保证非连通图的遍历*//*从第v个顶点出发递归地深度优先遍历图G*/if(!visited[v])DFS(G,v);}6.3图的遍历算法6.8利用邻接矩阵实现连通图的深度优先遍历/*从第i个顶点出发递归地深度优先遍历图G*/voidDFS(GraphG,inti){intj;printf("%3c",G.V[i]);/*访问第i个顶点*/visited[i]=1;for(j=0;j<G.n;j++)
if((G.arcs[i][j]==1)&&(visited[j]==0))
DFS(G,j);//对i的尚未访问的邻接点j递归调用DFS}6.3图的遍历算法6.9用邻接表实现连通图的深度优先遍历/*从第i个顶点出发递归地深度优先遍历图G*/voidDFS(ALGraphG,inti){ArcNode*p;printf(“%3c”,G.adjList[i].data);//访问顶点ivisited[i]=1;p=G.adjList[i].firstArc;while(p!=NULL){if(visited[p->adjVex]==0)//未访问的邻接点DFS(G,p->adjVex);//递归调用DFSp=p->nextArc;}}6.3图的遍历广度优先遍历算法1.图的广度优先遍历广度优先搜索(Breadth_FirstSearch)遍历类似于树的按层次遍历。设图G的初态是所有的顶点均未访问过,在G中任选一顶点vi为源点,过程为:(1)首先访问出发点vi,并将其访问标志置为已被访问,即visited[i]=true;(2)依次访问顶点vi的所有邻接点w0,w1,……,wt;(3)再依次访问顶点w0,w1,……,wt的所有邻接点。(4)如此类推,直至图中所有的顶点都被访问到。6.3图的遍历从顶点V1出发的广度优先搜索遍历序列可能有多种,这里只给出其中的三种,其它的可类似分析。这三种广度优先搜索遍历序列为:v1,v2,v3,v4,v5,v6,v7,v8v1,v3,v2,v7,v6,v5,v4,v8v1,v2,v3,v5,v4,v7,v6,v86.3图的遍历2.图的广度优先遍历操作算法6.10对图进行广度优先遍历voidBFSTraverse(GraphG){intv;for(v=0;v<G.n;v++)//初始化标志数组
visited[v]=0;for(v=0;v<G.n;v++)//保证全图的遍历
if(!visited[v])BFS(G,v);//从第v个顶点出发递归地广度优先遍历图G}
6.3图的遍历算法6.11广度优先遍历以邻接矩阵存储的图//从第k个顶点出发广度优先遍历图G,G以邻接矩阵表示voidBFS(GraphG,intk){inti,j; InitQueue(&Q);/*初始化队列*/printf("%3c",G.V[k]);/*访问第k个顶点*/visited[k]=1;EnQueue(&Q,k);/*第k个顶点进队*/while(!QueueEmpty(&Q))/*队列非空*/{DelQueue(&Q,&i);6.3图的遍历for(j=0;j<G.n;j++){if((G.arcs[i][j]==1)&&(visited[j]==0)){/*访问第i个顶点的末曾访问的顶点j*/printf("%3c",G.V[j]);visited[j]=1;EnQueue(&Q,j);/*第k个顶点进队*/}}}}6.3图的遍历算法6.12广度优先遍历以邻接表存储的图voidBFS(ALGraphG,intk){inti;ArcNode*p;InitQueue(&Q);/*初始化队列*/printf(“%3c”,G.adjList[k].data);//访问顶点kvisited[k]=1; EnQueue(&Q,k);/*第k个顶点进队*/while(!QueueEmpty(&Q))/*队列非空*/
{
DelQueue(&Q,&i);p=G.adjList[i].firstArc;/*获取第1个邻接点*/6.3图的遍历while(p!=NULL){if(visited[p->adjVex]==0){/*访问第i个顶点的末曾访问的顶点*/printf("%3c",G.adjList[p->adjVex].data);visited[p->adjVex]=1;EnQueue(&Q,p->adjVexp=p->nextArc;}p=p->nextArc;}}}
6.4图与最小生成树6.4图与最小生成树生成树和森林的概念在一个有n个顶点的连通图G中,存在一个极小的连通子图G’,G’包含图G的所有顶点,但只有n-1条边,并且G’是连通的,称G’为G的生成树。6.4图与最小生成树由深度优先搜索得到的生成树称为深度优先生成树,简称为DFS生成树;由广度优先搜索得到的生成树称为广度优先生成树,简称为BFS生成树。无向图G11的两种生成树无向图G11深度优先生成树广度优先生成树6.4图与最小生成树若一个图是非连通图或非强连通图,但有若干个连通分量或若干个强连通分量,则通过深度优先搜索遍历或广度优先搜索遍历,不能得到生成树,但可以得到生成森林,且若非连通图有n个顶点,m个连通分量或强连通分量,则可以遍历得到m棵生成树,合起来为生成森林,森林中包含n-m条树边。6.4图与最小生成树最小生成树无向连通带权图G的权为生成树T中各边的权值总和;边的权值总和最小的生成树,称为最小代价生成树(MinimumcostSpanningTree,MST)。构造最小生成树的准则如下:(1)必须只使用该网中的边来构造最小生成树;(2)必须使用且仅使用n-1条边来连接网中的n个顶点;(3)不能使用产生回路的边。6.4图与最小生成树最小生成树在带权的连通无向图G=(V,E)上,构造最小生成树有普里姆算法和克鲁斯卡尔算法,它们都是应用最小生成树MST的性质:U是顶点V的一个非空子集,若(u,v)是一条具有最小权值的边,其中u∈U,v∈V−U,则一定存在一棵包含边(u,v)的最小生成树。6.4图与最小生成树1.通过普里姆算法生成最小生成树(1)普里姆(Prim)算法的基本思想设G=(V,E)是带权图,V是图G的顶点集,E是边集。①在图中任取一个顶点k作为开始点,令U={k},W=V-U,TE={ф},其中W为图中剩余顶点的集合。②在由一个顶点在U中,另一个顶点在W中的两个顶点构成的所有边中,找出一条权值最小的边(u,v)(u∈U,v∈W),将该边作为最小生成树的树边放入TE,并将顶点v加入集合U中,并从W中删去这个顶点。③重复②,直到W为空集为止。此时TE中有n-1条边,此时T=(U,TE)就是G的一棵最小生成树。6.4图与最小生成树普里姆算法是从最小生成树中顶点的角度出发来考虑的,因为图中有n个顶点,按照生成树的定义,所有的顶点都必须加入到最小生成树中,所以除去最初选定的顶点,剩余的n-1个顶点在加入到最小生成树的过程中可以选择n-1条边加入到最小生成树的边集中。6.4图与最小生成树6.4图与最小生成树(2)普里姆算法的操作记录从顶点集U到V-U的代价最小的边需要设置一个MinEdge类型的辅助数组,类型定义如下:#defineMAXSIZE10typedefcharElemType;/*定义顶点类型*/typedefstruct{ ElemTypeadjvax;//U中的顶点
intlowcost;//边的权值}MinEdge;//记录从顶点集U到V-U的代价最小的边需要的辅助数组类型6.4图与最小生成树//求集合V-U依附于顶点u(u∈U)的权值最小的顶点的序号/*在辅助数组中求出权值最小的顶点序号*/intMinCost(GraphG,MinEdgee[]){inti,j,min;
for(i=0;i<G.n;i++)
if(e[i].lowcost!=0)break;
min=i;
for(j=i+1;j<G.n;j++)
if(e[j].lowcost!=0&&e[j].lowcost<e[min].lowcost)min=j;
returnmin;}
6.4图与最小生成树/*【算法6.13普里姆算法】*//*从顶点v出发构造网G的最小生成树,并输出最小生成树的各条边*/voidMiniSpanTree_PRIM(GraphG,ElemTypev){inti,j,k;
MinEdgee[MAXSIZE];
k=LocateVex(G,v);/*确定顶点v在网G中的序号*/
for(j=0;j<G.n;j++)/*初始化辅助数组*/
if(j!=k)
{e[j].adjvax=v;
e[j].lowcost=G.arcs[k][j]
}6.4图与最小生成树
/*初始顶点生成树集合,lowcost值为0,表示该顶点已并入生成树集合*/
e[k].lowcost=0;
for(i=0;i<G.n-1;i++)
{k=MinCost(G,e);//求辅助数组中权值最小顶点
/*输入最小生成树的一条边和对应的权值*/printf("(%c,%c,%d)“,e[k].adjvax,G.V[k],e[k].lowcost);
e[k].lowcost=0;//将顶点k并入生成树集合6.4图与最小生成树
for(j=0;j<G.n;j++)/*重新调整e*/
if(G.arcs[k][j]<e[j].lowcost)
{e[j].adjvax=G.V[k];
e[j].lowcost=G.arcs[k][j];
}
}
printf("\n");}表6.1给出了在用算法6.13构造图6.17的图G13的最小生成树的过程中,MinEdge类型数组元素的两个成员分量及两个集合的取值变化情况。
6.4图与最小生成树最小生成树1.通过普里姆算法生成最小生成树
e[vi]e[v1]e[v2]e[v3]e[v4]e[v5]e[v6]e[v7]UMinCostW=V-Uadjvexlowcostv10v118v1∞v1∞v1∞v12v14{v1}2{v2,v3,v4,v5,v6,v7}adjvexlowcostv10v118v1∞v1∞v69v10v14{v1,v6}4{v2,v3,v4,v5,v7}adjvexlowcostv10v713v1∞v1∞v69v10v10{v1,v6,v7}9{v2,v3,v4,v5}adjvexlowcostv10v713v1∞v51v60v10v10{v1,v6,v7,v5}1{v2,v3,v4}adjvexlowcostv10v713v45v50v60v10v10{v1,v6,v7,v5,v4}5{v2,v3}adjvexlowcostv10v36v40v50v60v10v10{v1,v6,v7,v5,v4,v3}6{v2}adjvexlowcostv10v30v40v50v60v10v10{v1,v6,v7,v5,v4,v3,v2}
{}6.4图与最小生成树6.4图与最小生成树2.通过克鲁斯卡尔算法生成最小生成树普里姆算法适用于稠密图,而克鲁斯卡尔算法适用于稀疏图。克鲁斯卡尔算法是从边的角度求图的最小生成树。克鲁斯卡尔算法考虑问题的出发点是为了使生成树上边的权值之和达到最小,这样应使生成树中每一条边的权值尽可能小。6.4图与最小生成树克鲁斯卡尔算法具体做法如下:(1)将图中所有边按权值递增顺序排列;(2)先构造一个只含n个顶点的子图;(3)依次选取权值较小的边,但要求后面选取的边不能与前面选取的边构成回路,若构成回路,则放弃该条边,再去选取后面权值较大的边。(4)重复第(3)步,在具有n个顶点的图中,选够n-1条边即可。图6.18是图6.17(a)带权无向图的克鲁斯卡尔算法构造最小生成树的过程。6.4图与最小生成树6.5最短路径6.5最短路径单源点到其余各顶点的最短路径
1.单源点最短路径的定义在网图中,求点A到点B的所有路径中,边的权值之和最短的那一条路径。这条路径就是两点之间的最短路径,并称路径上的第一个顶点为起点(Sourse),最后一个顶点为终点(Destination)。最短路径问题是图的一个比较典型的应用问题。而单源点最短路径是其中比较重的一个应用。设有向图G=(V,E)。以某指定顶点为源点,求从出发到图中其余各点的最短路径称为单源最短路径。6.5最短路径源点终点最短路径路径长度v6v1<v6,v1>2v6v2<v6,v7,v2>17v6v3<v6,v5,v4,v3>15v6v4<v6,v5,v4>10v6v5<v6,v5>9v6v7<v6,v7>4
通过表6.2可以看出,从v6出发到v3存在4条路径,分别是<v6,v1,v2,v3>、<v6,v7,v2,v3>、<v6,v5,v7,v2,v3>、<v6,v5,v4,v3>,这四条路径的长度分别是26,23,49,15。通过比较得出,<v6,v5,v4,v3>是v6到v3的最短路径。
6.5最短路径2.迪杰斯特拉(Dijlstra)算法迪杰斯特拉提出了按路长递增产生各顶点的最短路径算法。(1)迪杰斯特拉算法的基本思想把图中所有顶点分成两组,第一组包括已确定最短路径的顶点,第二组包括未确定最短路径的顶点,然后按最短路径长度递增的次序逐个把第二组的顶点加到第一组中,直至从源点出发可以到达的所有顶点都包括到第一组中。保持从源点到第一组各顶点的最短路径长度都不大于从源点到第二组的任何顶点的最短路径长度。每一个顶点都对应一个距离值,第一组顶点对应的距离值就是从源点到此顶点的只包括第一组的顶点为中间顶点的最短路径长度。6.5最短路径设v0是起始源点,S是已求得最短路径的终点集合。迪杰斯特拉算法的基本思想是:①V-S=未确定最短路径的顶点的集合,初始时S={v0},长度最短路径是边数为1且权值最小的路径。②下一条长度最短的路径:vi
V-S,先求出v0到vi且中间只经S中顶点的最短路径;上述最短路径中长度最小者即为下一条长度最短的路径,将所求最短路径的终点加入S中。③重复②直到求出所有终点的最短路径。6.5最短路径(2)迪杰斯特拉算法的实现为实现迪杰斯特拉算法,我们需要引入一个辅助数组D[i],用于保存从源点出发到达顶点vi的最短路径,其值为最短路径长度。①初始时,若源点到顶点vi有边,则D[i]为边上的权值;否则,D[i]为∞。从v0出发,长度最短的路径是(v0,vj),即D[j]=min{D[i]|vi∈V-S},将顶点vj加入S集合,同时将其从集合V-S中去掉;6.5最短路径②求下一条长度最短的路径:修改从v0出发到达集合V-S中所有顶点的最短路径的长度。这些路径可能是v0直达vk,或者是从v0出发经过S中的某一个或一些顶点。如果D[j]+arcs[j][k]<D[k](vk∈V-S),则修改D[k]为D[j]+arcs[j][k]。③最短路径中长度最小者即为下一条长度最短的路径,即D[j]=min{D[i]|vi∈V-S}。将顶点vj加入S集合,同时将其从集合V-S中去掉;④重复②和③直到求出所有顶点的最短路径。最短路径终点vi从v6顶点出发到其余各顶点的最短路径path[i]的变化情况i=0i=1i=2i=3i=4i=5i=6
dist[v1]path[v1]
2<v6,v1>
dist[v2]path[v2]
∞20<v6,v1,v2>17<v6,v7,v2>17<v6,v7,v2>17<v6,v7,v2>17<v6,v7,v2>dist[v3]path[v3]
∞∞∞∞15<v6,v5,v4,v3>
dist[v4]path[v4]
∞∞∞10<v6,v5,v4>
dist[v5]path[v5]
9<v6,v5>9<v6,v5>9<v6,v5>
dist[v6]path[v6]0
dist[v7]path[v7]
4<v6,v7>4<v6,v7>
vj
v1v7v5v4v3v2S{v6}{v6,v1}{v6,v1,v7}{v6,v1,v7,v5}{v6,v1,v7,v5,v4}{v6,v1,v7,v5,v4,v3}{v6,v1,v7,v5,v4,v3,v2}6.5最短路径voidDijkstra(GraphG,intv0,intpath[],intdist[])/*求有向图G的v0顶点到其余顶点v的最短路径,path[i]是v0到vi的最短路径上的前驱顶点,dist[i]是路径长度*/{ inti,j,v,w; intmin;ints[MAXSIZE]; for(i=0;i<G.n;i++)/*初始化s,dist和path*/ {s[i]=0;dist[i]=G.arcs[v0][i]; if(dist[i]<Max)path[i]=v0; elsepath[i]=-1;} dist[v0]=0;s[v0]=1;/*初始源点v0属于s集*/ /*循环求v0到某个顶点v的最短路径,并将v加入s集*/
6.5最短路径for(i=1;i<G.n-1;i++){min=Max; for(w=0;w<G.n;w++)//w不属于s且离v0更近 {if(!s[w]&&dist[w]<min) {v=w;min=dist[w];}} s[v]=1;/*顶点v并入s*/ for(j=0;j<G.n;j++)//更新最短路径及距离 {if(!s[j]&&(min+G.arcs[v][j]<dist[j])) {dist[j]=min+G.arcs[v][j];path[j]=v;} }}}
6.6AOV网与拓扑排序6.6AOV网与拓扑排序AOV网在一个有向图中,若用顶点表示活动,有向边表示活动间的先后关系,称该有向图为用顶点表示活动的网络(ActivityOnVertexnetwork,AOV)。若从顶点vi到顶点vj之间存在一条有向路径,称顶点vi是顶点vj的前驱,或者称顶点vj是顶点vi的后继。即若<vi,vj>是图中的边,则称顶点vi是顶点vj的直接前驱,顶点vj是顶点vi的直接后继。6.6AOV网与拓扑排序AOV网大工程被划分成许多子工程(称为活动)。在大工程实施过程中,有些活动开始是以它的所有前序活动的结束为先决条件的,必须在其他有关活动完成后才能开始;有些活动没有先决条件,可以安排在任意时间开始。AOV网是一种可以形象地反映出整个工程中各个活动之间前后关系的有向图。6.6AOV网与拓扑排序表6.4各课程先后依存关系表课程课程名称先修课程C1高等数学无C2C语言程序设计无C3离散数学C1,C2C4数据结构C2,C3C5Java程序设计C2C6编译方法C5,C7C7操作系统C4,C9C8数字逻辑C1C9计算机组成原理C8图6.20课程开设的先后关系AOV网6.6AOV网与拓扑排序拓扑排序拓扑排序(TopologicalSort)是图中重要的运算之一,在实际中应用很广泛。对给定的AOV网应首先判定网中是否存在环。检测的办法是对有向图进行拓扑排序(TopologicalSort),拓扑排序指按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则加上任意的次序关系,所得顶点的线性序列称之为拓扑排序序列。6.6AOV网与拓扑排序1.拓扑排序的定义给出有向图G=(V,E),对于V中的顶点的线性序列(v1,v2,…,vk),如果满足如下条件:若在G中从顶点vi到vj有一条路径,则在序列中顶点vi必在顶点vj之前,称该序列为G的一个拓扑序列。构造有向图的拓扑序列的过程称为拓扑排序。6.6AOV网与拓扑排序(1)拓扑排序的注意事项①在AOV网中,若不存在回路,则所有活动可排成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,那么该序列为拓扑序列。②拓扑序列不是唯一的。③对AOV网不一定都有拓扑序列。④将AOV图中顶点排成一个线性序列,若该线性序列中包含AOV网全部的顶点,则AOV网中无环,否则,AOV网中存在有向环,该网所代表的工程是不可行的。6.6AOV网与拓扑排序(2)拓扑序列的实际意义如果按照拓扑序列中的顶点次序进行每一项活动,就能够保证在开始每一项活动时,它的所有前驱活动均已完成,从而使整个工程顺序执行。6.6AOV网与拓扑排序2.拓扑排序的基本步骤①在AOV网中选一个入度为0的顶点(没有前驱)并输出它;②从AOV网中删除此顶点及从该顶点发出来的所有有向边;③重复①②两步,直到AOV网中所有的顶点都被输出或网中不存在入度为0的顶点。6.6AOV网与拓扑排序2.拓扑排序的基本步骤对图6.20进行拓扑排序。列举两种得到的拓扑有序序列:C1,C8,C9,C2,C3,C4,C7,C5,C6或 C1,C8,C9,C2,C5,C3,C4,C7,C66.7AOE网与关键路径6.7AOE网与关键路径AOE网若在带权的有向图中,以顶点表示事件;有向边表示活动;边上的权值表示活动的开销(如该活动持续的时间)。则称此带权的有向图为AOE(activityonedge)网。如果用AOE网来表示一项工程,可以如下信息:完成预定工程计划所需要进行的活动;每个活动计划的完成时间;要发生哪些事件以及这些事件与活动之间的关系。针对某一工程对应的AOE网,我们可以用确定关键路径的方法来验证该工程能否完成,并且要估计工程的完成所需要的时间以及确定哪些活动会影响工程进度。6.7AOE网与关键路径AOE网在AOE网中,只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始;只有在进入每个顶点的各有向边所代表的活动都已经结束后,该顶点所代表的事件才能发生。一个表示工程的AOE网应该是没有回路的有向网,网中仅存在一个入度为0的顶点,称作开始顶点(源点),它表示整个工程的开始;网中仅存在一个出度为0的顶点,称为结束顶点(汇点),它表示整个工程的结束。6.7AOE网与关键路径图6.21是一个有9个活动11个事件的AOE网。顶点v1、v2、…、v9表示事件;<v1,v2>,<v1,v3>,<v1,v4>…<v8,v9>表示活动。其中v1为开始顶点,入度是0;v9为结束顶点,出度是0。6.7AOE网与关键路径关键路径1.相关术语(1)AOE网的路径长度AOE网的路径长度是该路径上各个活动所需时间的总和。(2)关键路径由于AOE网中的某些活动能够同时进行,故完成整个工程所必须花费的时间应该为:源点到终点的最大路径长度(路径长度是指该路径上的各个活动所需时间之和)。具有最大路径长度的路径称为关键路径。关键路径上的活动称为关键活动。6.7AOE网与关键路径(3)事件的最早发生时间ve(i)从源点到顶点i的最大路径长度代表的时间,意味着所有以顶点i为弧尾的活动的最早开始时间计算方法如下:①令ve(1)=0,i=2;②ve(i)=Max{ve(k)+t(k,i)|k为i的直接前驱};③++i,重复②,直到i>n。6.7AOE网与关键路径(4)事件的最迟发生时间vl(i)事件vi允许的最晚发生时间vl(k)是指在不推迟整个工程工期(即保证结束顶点vn在ve(n)时刻发生)的前提下,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度原材料采购:木屑长期供应合同
- 2024年度代持能源权益合同
- 2024年度工程承包合同:基础设施建设施工合同
- 04版电子商务平台搭建与运营合同
- 2024年度物联网技术应用合同
- 湿式潜水衣市场发展现状调查及供需格局分析预测报告
- 贵金属制钥匙圈市场需求与消费特点分析
- 灯罩座市场发展现状调查及供需格局分析预测报告
- 2024年度智慧城市系统开发与应用合同
- 磁带录音机市场发展现状调查及供需格局分析预测报告
- 防渗墙验收、记录表
- 市心血管重点专科汇报材料
- 工程量确认单[]
- 出境领队服务程序与规范(共36页).ppt
- 数控线切割中级工试题
- 华为物料品质试验中心KPI指标体系
- 机械零件轴测图精品
- 国培计划操作手册
- 英语《花木兰》短剧剧本
- 入侵报警系统工程施工要求及调试
- 基于PLC的燃油锅炉控制系统设计毕设设计说明书论文
评论
0/150
提交评论