有关最短路径,我就是因为自己的需要先直接写迪杰斯特拉算法和弗洛伊德算法,其他的(图的遍历,图的存储结构,图的其他应用)日后再温习。(太垃圾了太垃圾)
最短路径
一.迪杰斯特拉算法:
1.迪杰斯特拉算法的求解过程:
//V 为顶点的有穷非空集合,E为V中顶点偶对的有穷集合,这些顶点的偶对称为边,即E为边的集合。
对于网 N=(V,E),将N中的定点分成两组:
第一组S:已求出最短路径的终点集合(初始时只包含源点v0)。
第二组V-S: 尚未求出的最短路径的顶点集合(初始时为V-{v0})。
算法将按各顶点与v0间最短路径长度递增的次序,逐个将集合V-S中顶点的个数加入到S中去。在这个过程中,总保持从v0到集合S中各顶点的路径长度始终不大于集合V-S中各顶点的路径长度。
2.迪杰斯特拉算法的实现:
假设用带权的邻接矩阵arcs 来表示带权有向图G,G.arcs[i][j]表示弧<vi,vj>上的权值。若<vi,vj>不存在,则置G.arcs[i][j]为,源点为v0.
算法的实现要引入以下辅助的数据结构:
(1).一维数组S[i]:记录从源点v0到终点vi是否已被确定最短路径,true 表示确定,false表示尚未确定。
(2).一维数组Path[i]:记录从源点v0到终点vi的当前最短路径上vi的直接前驱顶点序号。其中初值为:如果从v0到vi有弧,则Path[i]为v0,否则为-1;
(3).一位数组D[i]:记录从源点v0到终点vi的dan当前的最短路径长度。其初值:如果从v0到vi有弧,则D[i]为hu'c弧上的权值,否则为。
显然,长度最短的一条最短路径为(v0,vk),man满足一下条件:
D[k]=Min{D[i]|viV-S}
求得顶点vk的最短路径后,将其加入到第一组顶点集S中去。
(当加入新的顶点后,对第二组剩余的各个顶点而言,多了一个”中转“路径。假设原来从源点v0到vi的最短路径为D[i],加入vk之后,以vk作为中间顶点的”中转“路径长度为:D[k]+G.arcs[k][i],若D[k]+G.arcs[k][i]<D[i],则D[k]+G.arcs[k][i]将代替D[i]。)
3.迪杰斯特拉算法
(1).算法步骤:
A>.初始化:
a>.将源点v0jia加入到中,即S[0]=v0;
b>.将v0到各个终点的zui'最短路径长度初始化为权值,即D[i]=G.arcs[v0][vi],(viV-S);
c>.如果v0和各个顶点vi之间有弧,则将vi的qia前驱置为v0,即Path[i]=v0,否则,Path[i]=-1.
B>循环n-1次,执行以下操作:
a>.选择下一条zui'最短路径的终点vk,使得:D[k]=Min{D[i]|viV-S};
b>.将vk加入到S中,ji即S[i]=true;
c>.根据条件更新从v0出发的集合V-S上任一顶点的最短路径的长度,若条件D[k]+G.arcs[k][i]<D[i]成立,则更新D[i]=D[k]+G.arcs[k][i],同时更改vi的直接前驱为vk;Path[i]=k.
(2算法描述:(注意,由于今天时间有限,代码还没敲完,此代码为伪代码,c++,但是基本完善。)
void shortestPath-DIJ(AMGraph,int v0)
{
n=G.vexnum;
for(v=0;v<n;v++){
S[v]=false;
D[v]=G.arcs[v0][v];
if(D[v]<MaxInt)
Path[v]=v0;
else
Path[v]=-1;
}
}