图的应用基础

一、图的类型

名称 特征
无向图 边没有方向
有向图 边有方向
加权无向图 边有权值但没有方向
加权有向图 边有权值且有方向

 

 

 

 

 

二、图的表示:G = (V, E)

1、邻接表

对V的每个顶点都用一个表来表示,每个表中包含所有与该顶点相邻的顶点组成,所有的表构成图的邻接表。

具体实现形式:每个表中的数据格式可为:顶点编号、顶点的度、依次列出与该顶点相邻的顶点编号。可用vector类型的数组来表示: vector<int> G[n]。

2、邻接矩阵

用|V|*|V|的矩阵来表示,顶点i到顶点j存在边则aij为1 

 

三、图的搜索算法

1、深度优先搜索

 以“能走多远就走多远”为基本规则。对顶点v的边进行递归搜索,当v的边全部搜索完毕后,则回归并继续搜索前一顶点。

需要对各顶点记录两个时间节点:d[v], 记录第一次访问v的时刻;f[v], 记录调查完v的邻接表的时刻。

实现过程及其变量:

1. 从最初访问的顶点0开始,将其压入栈中(Stack S)
2. 只要栈中仍然有顶点,就循环下述操作
        访问栈顶部的顶点u;
        从当前访问的顶点u移动至与其相邻的顶点v时,将v压入栈中。若当前顶点u不存在未访    
        问的相邻顶点,则将u从栈中删除;
3. 若仍有顶点未被发现,则选择其中编号最小的作为新的起点继续搜索。

用枚举类型来标记各个顶点的访问状态(未访问、当前被访问、访问过的点、访问结束的点)
邻接矩阵
栈,用于暂存访问过程中的顶点

  

2、广度优先搜索

尽可能地搜索与已搜索顶点相邻的未搜索顶点,再以此类推不断扩大搜索范围。可用作求最短路径的一个算法。

会记录各顶点v到起点s的距离d[v]

实现过程及其变量:

1. 将起点s放入队列Q中
2. 只要Q不为空,则循环执行下述处理
        从Q中取出顶点u进行访问(访问结束);
        将与u相邻的未访问顶点v放入Q中,并将d[v]更新为d[u]+1 ;

标记顶点状态:未访问、当前访问、队列中的顶点、访问结束。
邻接矩阵
队列Q
最短距离数组d[n]

  

四、加权图

1、基本概念

最小生成树:利用图生成的树中,各边权值总和最小;

最短路径问题:求出给定两顶点之间各边权值总和最小的路径;

最短路径生成树:在各边非负的加权图中,若顶点s到G的所有顶点都存在路径,则一定存在一棵以s为根,且s到所有顶点最短路径的生成树;

2、算法

   (1). 普里姆算法,生成最小生成树

设图G = (V, E)所有顶点的集合为V, MST中顶点的集合为T.
1. 从G中选取任意顶点作为MST的根,将其添加至T;
2. 循环执行下述处理直至T = V
        在连接T内顶点与V-T内顶点的边中选取权值最小的边(P[u], u),将其作为MST的边,并将u添加到T中,用于搜索之前未查找过的边(u作为起点);

  

  (2).迪克斯特拉算法

  求给定加权有向图G = (V, E)的单源最短路径的成本。以顶点0为起点,找出0到各顶点的最短路径上各边权值的总和。

其基本原则与普利姆算法类似
设所有的顶点集合为V,最短路径树中包含的顶点集合为S,且起点为s。
顶点s到i的最短路径为d[i],i在最短路径树中的父节点为p[i].

循环直至S=V为止
        从V-S中选出d[u]最小的顶点u;
        将u添加至S中,同时将与u相邻且属于V-S中的所有顶点v的d[v]值按照如下方式更新:
            if d[u] + w(u, v) < d[v]
                d[v] = d[u] + w(u, v)
                p[v] = u

  注意:该算法不适用于包含负权值的图,负权值的图可使用贝尔曼-福特算法或弗洛伊德算法来处理。

  

3. 为了改善算法复杂度,将放弃邻接矩阵来表示图的方法,而利用二叉堆(优先级队列)和邻接表表示法。

  也就是采用二叉堆或者优先级队列来存放节点 Node(v, d[v]),从而可快速的取出顶点,降低算法复杂度。

posted @ 2017-10-21 15:47  zmlgo  阅读(287)  评论(0)    收藏  举报