遍历定义——从已给的连通图中某一顶点出发,沿着一边访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历,它是图的基本运算。
遍历实质——找每个顶点的邻接点的过程。
图的特点——图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回了曾经访问过的顶点。
深搜例子:
例子:
void DFS(AMGraph G,int v){ //图G为邻接矩阵类型
cout<<v; visited[v]=true; //访问第v个顶点
for(int w=0;w<G.vexnum;w++) //依次检查邻接矩阵v所在的行
if(G.arc[v][w]!=0&&(!visited[w]))
DFS(G,w);
// w是v的邻接点,如果w为访问,则递归调用DFS
}
广搜例子:
例:
// 按广度优先非递归遍历连通图
void BFS(Graph G int v){
cout<<v; visited[v]=true; //访问第v个顶点
InitQueue(Q); //辅助队列Q初始化,置空
EnQueue(Q,v); //v进队
while(!QueueEmpty(Q)) { //队列非空
DeQueue(Q,u); //对头元素出对并置为u
for(int w=FirstAdjVex(G,u);w>0;w=NextAdjVex(G,u,w))
if(!visited[w]){ // w为u的尚未访问的邻接顶点
cout<<w; visited[w]=true; EnQueue(Q,w); //w进队
} // if
} // while
} // BFS
最小生成树的典型应用
构造最小生成树的算法很多,其中多数算法都利用了MST的性质。
MST性质:设 N = ( V , E ) N=(V,E) N=(V,E)是一个连通网, U U U顶点集 V V V的一个非空子集。若边 ( u , v ) (u,v) (u,v)是一条具有最小权值的边,其中 u ∈ U , v ∈ V − U u∈U,v∈V-U u∈U,v∈V−U,则必存在一棵包含边 ( u , v ) (u,v) (u,v)的最小生成树。
MST性质解释:
在生成树的构造过程中,图中n个顶点分属两个集合:
接下来则应在所有连通U中顶点的边中选取权值最小的边。
图示:
例子:
例子:
算法名 | 普里姆算法 | 克鲁斯卡尔算法 |
---|---|---|
算法思想 | 选择点 | 选择边 |
时间复杂度 | O ( n 2 ) O(n^2) O(n2)( n n n为顶点数) | O ( e l o g e ) O(eloge) O(eloge)( e e e为边数) |
适应范围 | 稠密图 | 稀疏图 |
如何能够使一个地点到另一个地点的运输时间最短或运费最省?这就是一个求两个地点间的最短路径问题。
最短路径与最小生成树不同,路径上不一定包含n个顶点,也不一定包含n-1条边。
1.初始化:先找到从源点 v 0 v_0 v0到各终点 v k v_k vk的直达路径 ( v 0 , v k ) (v_0,v_k) (v0,vk),即通过一条弧到达的路径。
2.选择:从这些路径中找出一条长度最短的路径 ( v 0 , u ) (v_0,u) (v0,u)。
3.更新:然后对其余各条路径进行适当调整。
若在图中存在弧 ( u , v k ) (u,v_k) (u,vk),且 ( v 0 , u ) + ( u , v k ) < ( v 0 , v k ) (v_0,u)+(u,v_k)<(v_0,v_k) (v0,u)+(u,vk)<(v0,vk),则以路径 ( v 0 , u , v k ) (v_0,u,v_k) (v0,u,vk)代替 ( v 0 , v k ) (v_0,v_k) (v0,vk)。
在调整后的各条路径中,在找长度最短的路径,以此类推。
迪杰斯特拉(Dijkstra)算法:按路径长度递增次序产生最短路径
1、把V分成两组:
2、将 T T T中顶点按最短路径递增的次序加入到 S S S中
保证:
例子:
求所有顶点间的最短路径:
方法一:每次以一个顶点为源点,重复执行Dijkstra算法n次——时间复杂度: O ( n 3 ) O(n^3) O(n3)
方法二:弗洛伊德(Floyd)算法——时间复杂度: O ( n 3 ) O(n^3) O(n3)
算法思想:
例子:
针对特殊的图——有向无环图
AOV网:
用一个有向图表示一个工程的各子工程及其相互制约的关系,其中以顶点表示活动,弧表示活动之间的制约关系,称这种有向图为顶点表示活动的网,简称AOV网(Activity On Vertex)。
AOE网:
用一个有向网表示一个工程的各子工程及其相互制约的关系,以弧表示活动,以顶点表示活动的开始或结束事件,称这种有向图为边表示活动的网,简称AOE网(Activity On Edge)
例子:
问题例子:
把工程计划表示为边表示活动的网络,即AOE网,用顶点表示事件,弧表示活动,弧的权值表示活动持续时间。
事件表示在它之前的活动已经完成,在它之后的活动可以开始。
对于AOE网,我们关心两个问题:——求解关键路径问题
关键路径——路径长度最长的路径
路径长度——路径上各活动持续时间之和。
如何确定关键路径,需要定义4个描述量:
l ( i ) − e ( i ) l(i)-e(i) l(i)−e(i)——表示完成活动 a ( i ) a(i) a(i)的时间余量。eg: l ( 3 ) − e ( 3 ) = 90 l(3)-e(3)=90 l(3)−e(3)=90
关键活动——关键路径上的活动,即 l ( i ) = = e ( i ) l(i)==e(i) l(i)==e(i)。(即 l ( i ) − e ( i ) = = 0 l(i)-e(i)==0 l(i)−e(i)==0)的活动。
例: