数据结构-合肥工业大学 7_第1页
数据结构-合肥工业大学 7_第2页
数据结构-合肥工业大学 7_第3页
数据结构-合肥工业大学 7_第4页
数据结构-合肥工业大学 7_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章图★基本术语★图的存储结构★图的遍历★最小生成树和最短路径问题★AOV网与拓扑排序★AOE网与关键路径7.1基本术语

图是由顶点的非空有穷集合与顶点之间关系(边或弧)的集合构成的结构,通常表示为

G=(V,E)其中,V为顶点集合,E为关系(边或弧)的集合.一.图的定义关于一条边或弧的表示方法:vjvivjvivjvivjvi(1).用图形:

(vi,vj)(2).用符号:(b).

这条边依附于顶点vi和vj。(a).顶点vi与vj

是这条边的两个邻接点。(3).用语言:v1v2v3v4

其中

V1={v1,v2,v3,v4}E1={(v1,v2),(v1,v3),(v1,v4),(v2,v3),(v2,v4),(v3,v4)}G1=(V1,E1)v1v2v3v4其中

V2={v1,v2,v3,v4}E2={<v1,v2>,<v2,v1>,<v2,v3>,<v4,v3>}G2=(V2,E2)

无向图:

有向图:与边有关的数据称为权,边上带权的图称为网络。二.图的分类对于(vi,vj)E,必有(vj,vi)E,并且偶对中顶点的前后顺序无关。若<vi,vj>E是顶点的有序偶对。

网(络):v1v2v3v4v1v2v3v4v1v2v3v4104178

1.顶点的度对于有向图而言,有:

顶点的出度:

以顶点vi为出发点的边的数目,记为OD(vi).

顶点的入度:

以顶点vi为终止点的边的数目,记为ID(vi).

TD(vi)=OD(vi)+ID(vi)三.名词术语依附于顶点vi的边的数目,记为TD(vi).v1v2v3v4v1v3v4v2

边的数目达到最大的图称为完全图.边的数目达到或接近最大的图称为稠密图,否则,称为稀疏图.具有n个顶点的有向图最多有n(n-1)条边.具有n个顶点的无向图最多有n(n-1)/2条边.对于具有n个顶点,e条边的图,有

2e=

TD(vi)ni=1结论1结论2结论3

2.

路径DCEBAP(A,E):

A,B,EA,C,D,E

出发点与终止点相同的路径称为回路或环;顶点序列中顶点不重复出现的路径称为简单路径。不带权的图的路径长度是指路径上所经过的边的数目,带权的图的路径长度是指路径上经过的边上的权值之和。顶点vx到vy之间有路径P(vx,vy)的充分必要条件为:存在顶点序列vx,vi1,vi2,…,vim,vy,

并且序列中相邻两个顶点构造的顶点偶对分别为图中的一条边。

3.子图v1v2v3v4对于图G=(V,E)与G´=(V´,E´),若有V´

V,E´

E,则称G´为G的一个子图.v1v2v3v4v1v2

4.图的连通无向图中顶点vi到vj

有路径,则称顶点vi与vj

是连通的。若无向图中任意两个顶点都连通,则称该无向图是连通的。若有向图中顶点vi到vj

有路径,并且顶点vj

到vi也有路径,则称顶点vi与vj

是连通的。若有向图中任意两个顶点都连通,则称该有向图是强连通的。(1).无向图的连通(2).有向图的连通

5.生成树

包含具有n个顶点的连通图G的全部n个顶点,仅包含其n-1条边的连通子图称为G的一个生成树。v1v3v4v2v1v3v4v2v1v3v4v2v1v3v4v2v1v3v4v2对于一个图,需要存储的信息应该包括:(1).所有顶点的数据信息;(2).顶点之间关系(边或弧)的信息;(3).权的信息。7.2图的存储结构一.邻接矩阵存储方法核心思想:采用两个数组存储一个图.1.定义一个一维数组VERTEX[1:n]存放图中所有顶点的数据信息.2.定义一个二维数组A[1:n,1:n]存放图中所有顶点之间关系的信息(该数组被称为邻接矩阵),有

1

当顶点vi到顶点vj有边时A[i,j]=

0

当顶点vi到顶点vj无边时

对于带权的图,有

wij

当顶点vi到顶点vj有边,且边的权为wij

A[i,j]=

当顶点vi到顶点vj无边时

oo数组存储方法0111101111011110A1=v1v2v3v4Vertex1[1:4]v1v2v3v4Vertex2[1:4]

4

6

7

8

A2=v1v2v3v4v1v2v3v4104178(1).无向图的邻接矩阵一定是一个对称矩阵.(2).不带权的有向图的邻接矩阵一般是一个稀疏矩阵。(3).无向图的邻接矩阵的第i行(或第i列)非0或非

元素的个数为第i个顶点的度数.(4).有向图的邻接矩阵的第i行非0或非元素的个数为第i个顶点的出度;第i列非0或非元素的个数为第

i个顶点的入度。特点:二.邻接表存储方法核心思想:对具有n个顶点的图建立n个线性链表存储该图.1.每一个链表前面设置一个头结点,用来存放一个顶点的数据信息,称之为顶点结点.其结构为:vertexlink其中,vertex

域存放某个顶点的数据信息;

link域存放某个链表中第一个结点的地址.2.第i个链表中的每一个链结点(称之为边结点)表示以第i

个顶点为出发点的一条边;边结点的构造为nextweightadjvex其中,next

域为指针域;

weight

域为权值域(若图不带权,则无此域);

adjvex

域存放以第i个顶点为出发点的一条边的另一端点在头结点数组中的位置.n个头结点之间为一数组结构.1234v1v2v3v447861233^^^^

(1).无向图的第i个链表中边结点的个数是第i个顶点度数.(2).有向图的第i个链表中边结点的个数是第i个顶点的出度。特点^^^^1234v1

v3v2v4234332411421v1v2v3v4v1v2v3v46478Typeedgeptr=

edgenode;定义一个指向结点的指针类型

edgenode=record定义一个结点类型

adjvex:1..n;顶点编号

weight:real;边的权值

next:edgeptr;指向下一个结点的指针

end;

vexnode=record定义一个头结点类型

vertex:vertype;顶点类型

link:edgeptr;指向第一个顶点的指针

end;

adj_list=Array[1..n]ofvexnode;定义一个数组,数组内容类型为头结点类型

邻接表的类型定义(Pascal)邻接表的类型定义(C语言)Typeedgeptr=

edgenode;定义一个指向结点的指针类型

edgenode=record定义一个结点类型

adjvex:1..n;顶点编号

weight:real;边的权值

next:edgeptr;指向下一个结点的指针

end;

vexnode=record定义一个头结点类型

vertex:vertype;顶点类型

link:edgeptr;指向第一个顶点的指针

end;

adj_list=Array[1..n]ofvexnode;定义一个数组,数组内容类型为头结点类型

建立邻接表的算法:

Procedurebuild_adjlist(var

ga:adj_list)Beginread(n,e);fori:=1tondo[ga[i].vertex:=i;

ga[i].link:=nil;]fork:=1toedo[read(i,j);new(p);

p^.adjvex:=j;p^.next:=ga[i].link;

ga[i].link:=p;]end;1234v1v2v3v46412^^7284^^三.有向图的十字链表存储方法

(略)

四.无向图的多重邻接表存储方法

(略)关于逆邻接表v1v2v3v46478ADEFCBABCDEF^^^^^^12345623461341245123534615例

已知一具有n个顶点的无向图G采用邻接表存储方法,

写一算法,删除图中数据信息为item的那个顶点.需要做的工作:

(1).寻找满足条件的那个顶点;(2).从头结点数组中删除该顶点;(3).删除与该顶点相关的边;(4).修改有关的边结点的adjvex

域的内容。ADEFCBABCDEF^^^^^12345623461341245123534615ADEFCBABDEFF^^123456235131243514^^^procedureDel(g,n,item);begink:=0;fori:=1tondo

if(g[i].vertex=item)then[k:=i;exit;]if(k=0)thenreturn;p:=g[k].link;

fori:=k+1tondo[g[i-1].vertex:=g[i].vertex;g[i-1].link:=g[i].link;]n:=n–1;//顶点的个数减1//

while(p<>nil)do[q:=p;p:=p.next;dispose(q);]

fori:=1tondo[p:=g[i].link;while(p<>nil)do

if(p.adjvex=k)then[if(g[i].link=p)then

g[i].link[i]:=p.nextelse

q.next:=p.next;r:=p;p:=p.next;

dispose(r);]else[if(p.adjvex>k)then

p.adjvex:=p.adjvex–1;q:=p;p:=p.next;]]end;

从图中某个指定的顶点出发,按照某一原则对图中所有顶点都访问且仅访问一次,得到一个由图中所有顶点组成的序列,这一过程称为图的遍历.原则:

从图中某个指定的顶点v出发,先访问顶点v,然后从顶点v未被访问过的一个邻接点出发,继续进行深度优先遍历,直到图中与v相通的所有顶点都被访问;若此时图中还有未被访问过的顶点,则从另一个未被访问过的顶点出发重复上述过程,直到遍历全图.一.深度优先搜索7.3图的遍历

为了标记某一时刻图中哪些顶点是否被访问,定义一维数组visited[1:n],有

1

表示第i个顶点已经被访问

visited[i]=

0

表示第i个顶点还未被访问

13684257123456^^^^^^123456231451672828387878^38^47562345678例:用深度优先算法遍历下图中的G从V1出发的访问序列为:V1,V2,V4,V8,V5,V6,V3,V7深度优先遍历的非递归算法:Proceduredfs(g:adj-list;v0:integer);

Begin

Initstack(s);write(v0);visited[v0]:=1;p:=g[v0].link;while(p<>nil)or(notempty(s))do[whilep<>nildoIfvisited[p^.adjvex]=1thenp:=p^.next;else[w:=p^.adjvex;write(w);visited[w]:=1;push(s,p);p:=g[w].link;]Ifnotempty(s)then[pop(s,p);p:=p^.next;]]end;二.广度优先搜索原则:

从图中某个指定的顶点v出发,先访问顶点v,然后依次访问顶点v的各个未被访问过的邻接点,然后又从这些邻接点出发,按照同样的规则访问它们的那些未被访问过的邻接点,如此下去,直到图中与v相通的所有顶点都被访问;若此时图中还有未被访问过的顶点,则从另一个未被访问过的顶点出发重复上述过程,直到遍历全图.13684257123456^^^^^^123456231451672828387878^38^47562345678例:用广度优先算法遍历下图中的G从V1出发的访问序列为:V1,V2,V3,V4,V5,V6,V7,V8广度优先遍历的算法如下:

Procedurebfs(g:adj-list;v0:integer);Beginvisited[v0]:=1;write(v0);f:=0;r:=0;p:=g[v0].link;

REPEATWhilep<>nildo[v:=p^.adjvex;if(visited[v]=0)then[r:=r+1;q[r]:=v;write(v);//入队并打印

visited[v]:=1;]p:=p^.next;]Iffrthen[f:=f+1;v:=q[f];p:=g[v].link;]UNTIL(p=

)AND(f=r)

end;

可以用深度优先搜索或广度优先搜索算法来判断图是否连通。在对无向图进行遍历时,对于连通图,仅需要一次搜索过程,图中的顶点就全部被访问。对于非连通图,则需要多次调用搜索过程,而每次调用得到的顶点访问序列恰好为其各个连通分量中的顶点集。三.求图的连通分量算法:

procedurecomponent(varg);beginfori:=1tovnumdovisited[i]:=0;count:=0;fori:=1tovnumdoifvisited[I]=0then[count:=count+1;dfs(g,i);]end;7.4最小生成树和最短路径问题

带权连通图中,总的权值之和最小的带权生成树为最小生成树.最小生成树也称最小代价生成树,或最小花费生成树.构造网的最小生成树的依据:在网中选择n-1条边,连接网的n个顶点;2.尽可能选取权值为最小的边。最小生成树的概念:最小生成树问题v4v2v6v5v3v116115691814192220最小生成树的权值

=56Kruskal算法:

1.设T的初态为空集;

2.当T中边数小于n-1时做下列工作①从E中选取权值为最小的边(v,w),并删除之;②若(v,w)不和T中的边一起构成回路,则将边(v,w)加入到T中去。1246536536215465124653①T为空124653②选权值最小的边(1,3)

从E中将其删去11246531③选E中最小的边(4,6)从E中将其删去212465312④从E中选最小的边(2,5)从E中将其删去3124653123⑤从E中选最小的边(3,6)从E中将其删去4⑥从E中选最小的边(3,4),但加入T后会使T中出现回路,所以边(3,4)不可取,把边(3,4)从E中删除。再看(1,4)同样会使T构成回路,仍不可取,从E中删去(1,4),选(2,3),从E中删去(2,3),最后已够5条边了,这样生成树就是最小生成树。最小生成树可能不唯一,但权的总数相同。24653123415算法的思想明确、也很简单,但具体实现时比较困难,需要解决一些具体的问题,譬如如何所选的新边没有和已选的边构成回路。算法讨论:Prim算法:

1.设V(T)的初态为空集(V(T)为落在生成树上的顶点集合);2.在连通图上任选一顶点加入到V(T)集合中去;

3.将下列步骤重复n-1次:①在i属于V(T),j不属于V(T)的边中,选权值最小的边

(i,j);②将顶点j加入到V(T)中去;③输出i,j及Wij。例:①初态V(T)=φ

②选①顶点=>V(T)={1}③做n-1次1)边(1,2)的权值最小,∴将②=>V(T)={1,2};write(1,2)weight161246532)边(2,3)的权值最小,∴将③=>V(T)={1,2,3};write(2,3)weight53)边(3,4)的权值最小,∴将④=>V(T)={1,2,3,4};write(3,4)weight6165618192111143364)边(2,6)的权值最小,∴将⑥=>V(T)={1,2,3,4,6};write(2,6)weight115)边(4,5)的权值最小,∴将⑤=>V(T)={1,2,3,4,5,6};write(4,5)weight18∑i=16Weight=5612465316561819211114336124653165618117.5最短路径问题一.路径长度的定义1.不带权的图:路径上所经过的边的数目。2.带权的图:路径上所经过的边上的权值之和.二.问题的提出设出发顶点为v(通常称为源点)。确定源点到其他各顶点的最短路径,常应用于选择路线,架设电线等.013524455010201015152033530v0是源点最短路径v0→v210v0→v2→v310+15=25v0→v2→v3→v110+15+20v0→v445v0→v5无路可走从以上可以发现每一条最短路径中间所经过的顶点具有如下特点:下一条最短路径(设其终点为x)可能是<v0,x>,或者<v0,u,…,v,x>,而u,…,v都是已求得的最短路径终点。例假设S为已求得的最短路径的终点的集合(S初态为空集),则下一条长度次短的最短路径(设终点为x):或者是弧<v0,x>;或者是中间经过S集合中顶点,最后到达顶点x的路径。Dijkstra算法思想:2.设置一个标志数组S[1:n]记录源点v到图中哪些顶点的最短路径已经找到,有:

1表示源点到顶点i的最短路径已经找到

S[i]=

0

表示源点到顶点i的最短路径尚未找到初始时,

S[V0]=1,S[i]=0

i=1,2,,niv{3.设置数组dist[1:n]分别记录源点V0

到图中各顶点的最短路径的路径长度,其中,dist[i]记录源点到顶点i的最短路径的长度;初始时,dist数组的值为邻接矩阵第V0行的n个元素值。

4.设置数组path[1:n]分别记录源点V0

到图中各顶点的最短路径所经过的顶点序列,其中,path[i]记录源点到顶点i的路径,初始时,path[i]=

V0

,

i=1,2,3,,n三.解决问题所需要确定的数据结构1.图的存储:设cost为带权的邻接矩阵

当顶点vi到顶点vj

有边,且权为Wij

时,则

cost[i,j]=Wij

当顶点vi到顶点vj无边时cost[i,j]=

0

当vi=vj

四.算法(用自然语言表达)1.

确定dist、S、path三个数组的初值。2.利用S数组与dist数组在那些尚未找到最短路径的顶点中确定一个与源点最近的顶点u,即dist值最小的顶点并置

S[u]为1,同时将顶点u加入path[u].3.根据顶点u修改源点到所有尚未找到最短路径的顶点的路径长度。即

1)将源点V0到顶点u的(最短)路径长度分别加到源点

V0通过顶点u可以直接到达、且尚未找到最短路径那些的顶点的路径长度上;若加后的长度小于原来V0到某顶点r的路径长度,则用加后的长度替代原来的长度,否则不替代。

2)若替代,将源点V0到顶点u的路径(最短路径)上经过的所有顶点替换path[r].4.重复第2至第3步n-1次。fori1tondo

dist[i]cost[v,i]end

S[i]0S[v]1

path[i]{v}

Floyed算法思想:从i到j的路径上每次增加一个结点k,看这个增加了一个结点k的新路径的长度是否比原来的路径长度小,若小,则以新路径代之,否则保持原路径。A(k)[i,j]=min{A(k-1)[i,j],A(k-1)[i,k]+A(k-1)[k,j]}(1≤k≤n)算法计算公式:其中:A(k)[i,j]表示顶点i,j之间的中间点的序号不大于k的最短距离;

由于G中顶点编号不大于n,所以最后到了An[i,j]就代表i到j的最短路径之长。算法描述:procedureall_path(cost);Beginfori:=1tondoforj:=1tondo[a[i,j]:=cost[i,j];

if(i<>j)and(a[i,j]<max)then

path[i,j]=[i]+[j]]fork:=1tondofori:=1tondoforj:=1tondoifa[i,k]+a[k,j]<a[i,j]then[a[i,j]:=a[i,k]+a[k,j];

path[i,j]:=path[i,k]+path[k,j];]End;cost=04116023∞0cost:带权邻接矩阵A:最短路径长度P:相应的路径例:641132ABC321初态K=0时,A(0)123

1

2

304116023∞0

ABACPath(0)123

1

2

3BABCCA

K=1时,A(1)123Path(1)123104111ABAC26022BABC33703CACABK=2时,A(2)123Path(2)12310461ABABC26022BABC33703CACABK=3时,A(3)123Path(3)12310461ABABC25

022BCABC33703CACAB★AOV网与拓扑排序一.什么是AOV网验收筹备招标备料进驻工地测量挖地基浇注水泥搭架子…例1程序语言数据结构离散数学软件工程操作系统编译原理数据库计算机组成汇编网络数字逻辑计算机导论例2二.AOV网的定义

在AOV网中,若顶点i到顶点j之间有有向路径,则称顶点i为顶点j的前驱,顶点j为顶点i的后继;若顶点i到顶点j之间为一条有向边,则称顶点i为顶点j

的直接前驱,顶点j为顶点i的直接后继。以顶点表示活动,以有向边表示活动之间的优先关系的有向图称为AOV网。三.拓扑排序

检查AOV网是否存在回路的方法是对AOV网进行拓扑排序,构造一个序列,使得该序列满足条件:

1.若在AOV网中,顶点i优先于顶点j,则在该序列中也是顶点i优先于顶点j。

2.若在AOV网中,顶点i与顶点j之间不存在优先关系,则在该序列中建立它们的优先关系,即顶点i优先于顶点j,或顶点j优先于顶点i。

3.若能够构造出拓扑序列,则拓扑序列包含AOV网的全部顶点。

四.拓扑排序方法

1.从AOV网中任选择一个没有前驱(入度为0)的顶点;

2.从AOV网中去掉该顶点以及以该顶点为出发点的所有边;

3.重复上述过程,直到网中的所有顶点都被去掉,或者网中还有顶点,但不存在入度为0的顶点;

前者说明AOV网中无回路,后者说明AOV网中存在回路。v1v4v3v2v6v5v7v1v5v7v3v6v2v4例v4v3v2v6v7v4v3v2v6v5v7v4v3v2v7v4v3v7v4v7v7★AOE网与关键路径筹备付款签合同做预置件验收施工…招标7天联系材料8天图纸设计15天进驻工地4天运材料6天搬运3天例一.AOE网的定义

AOE网为一个带权的有向无环图,其中,顶点表示事件,有向边表示活动,边上的权值表示活动持续的时间。v1v4v2v3v5v7v9v8v6a1a2a3a4a5a6a7a8a9a10a1164511297244

正常情况下,AOE网中只有一个入度为0的顶点,称

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论