Dijkstra算法(迪杰斯特拉算法)
通过普里姆算法与克鲁斯卡尔算法,我们可以运算出最优全连通结果。但若要计算某个顶点与其他顶点连接的最短距离时,则需要了解地杰斯特拉算法(D算法)与弗洛伊德算法(F算法)
【例子】如下图,有一个7村庄(A~G),需要求得G村庄到其他村庄的最短距离
D算法流程:
visited_vertex数组:存储顶点是否被访问的信息(1为被访问)
pre_visited数组:存储对应结点的父节点
distance数组:存储对应结点距起始结点的距离
迪杰斯特拉算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。了解算法本质,就要读懂上面的流程图。
代码实现:
下面的代码实现有点复杂,需要借助两个类完成,一个是图结构的类,负责图的绘制与地杰斯特拉算法主体操作。一个是visitedVertex类,负责存储地杰斯特拉算法需要使用的数据与方法
其中 更新顶点数组数据的方法(update),找到最短距离顶点并更新数据的方法(updateVertex),地杰斯特拉算法主体(djs)三个方法是整个代码的灵魂,三者具有一定的依赖关系
package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.Dijkstra;
import java.util.Arrays;
interface IConstant{//常量类
public static final int INF = 99999;//定义INF为全局常量,INF为填充数据
}
public class 地杰斯特拉算法_Dijkstra_最短路径问题 implements IConstant {
public static void main(String[] args) {
//准备图
char[] vertex={'A','B','C','D','E','F','G'};
int[][] matrix={
{INF,5,7,INF,INF,INF,2},
{5,INF,INF,9,INF,INF,3},
{7,INF,INF,INF,8,INF,INF},
{INF,9,INF,INF,INF,4,INF},
{INF,INF,8,INF,INF,5,4},
{INF,INF,INF,4,5,INF,6},
{2,3,INF,INF,4,6,INF},
};
Graph graph=new Graph(vertex,matrix);
//调用地杰斯特拉算法
graph.djs(6);
}
}
class Graph{
private char[] vertex;//顶点数组
private int[][] matrix;//邻接矩阵
private VisitedVertex visitedVertex;//对已运算的顶点进行操作的类
public Graph(char[] vertex, int[][] matrix) {
this.vertex = vertex;
this.matrix = matrix;
}
/**
* 地杰斯特拉算法主体
* @param index 起始顶点
*/
public void djs(int index){
//进行对于起始顶点的初始化操作
visitedVertex=new VisitedVertex(vertex.length,index);
update(index);
//循环顶点个数-1次,来找到从起始顶点到每个顶点的最短距离
for (int i=1;i
==========(visited_vertex)=========
1 1 1 1 1 1 1
==========(pre_visited)=========
6 6 0 5 6 6 0
==========(distance)=========
2 3 9 10 4 6 0
G到A~G的最短路径分别为:2,3,9,10,4,6,0
Floyd算法(弗洛伊德算法)
相较于地杰斯特拉算法,弗洛伊德算法十分简单易懂。但简单易懂的代价就是时间复杂度很高(O(n^3))
【例子】如下图,有一个7村庄(A~G),需要求得某一村庄到其他村庄的最短距离
F算法分析:
弗洛伊德算法的核心是建立了三个顶点的关系,算法从A~G中遍历选取一个顶点 k 作为中间顶点,再从A~G中选取一个顶点 i 作为起始顶点,再A~G从中选取一个顶点 j 作为终止顶点。将 i 到 k,k 到 j 这两段距离求和,求和结果与原先的 i 到 j 的距离比较,若更小就采用这段距离,反之仍用原有距离。
比如说:以A为中间顶点,选取C为起始顶点,G为终止顶点,所得到的的C到G的距离为7+2=10,再与原有距离进行比较,小时采用10
这样的算法十分暴力,需要三层循环。
代码实现:
package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.Floyd;
import java.util.Arrays;
interface IConstant{//常量类
public static final int INF = 99999;//定义INF为全局常量,INF为填充数据
}
public class 弗洛伊德算法_Floyd_最短路径问题 implements IConstant{
public static void main(String[] args) {
//准备图
char[] vertex={'A','B','C','D','E','F','G'};
int[][] matrix={
{0,5,7,INF,INF,INF,2},
{5,0,INF,9,INF,INF,3},
{7,INF,0,INF,8,INF,INF},
{INF,9,INF,0,INF,4,INF},
{INF,INF,8,INF,0,5,4},
{INF,INF,INF,4,5,0,6},
{2,3,INF,INF,4,6,0},
};
Graph graph=new Graph(vertex,matrix);
graph.floyd();
}
}
class Graph{
private char[] vertex;
private int[][] dis;
private int[][] pre;
public Graph(char[] vertex, int[][] matrix) {
this.vertex = vertex;
this.dis = matrix;
pre = new int[vertex.length][vertex.length];
for (int i=0;i
由A到A~G的最短距离分别为:[0] [5] [7] [12] [6] [8] [2]
由B到A~G的最短距离分别为:[5] [0] [12] [9] [7] [9] [3]
由C到A~G的最短距离分别为:[7] [12] [0] [17] [8] [13] [9]
由D到A~G的最短距离分别为:[12] [9] [17] [0] [9] [4] [10]
由E到A~G的最短距离分别为:[6] [7] [8] [9] [0] [5] [4]
由F到A~G的最短距离分别为:[8] [9] [13] [4] [5] [0] [6]
由G到A~G的最短距离分别为:[2] [3] [9] [10] [4] [6] [0]
其他常用算法,见下各链接
【常用十大算法_二分查找算法】
【常用十大算法_分治算法】
【常用十大算法_贪心算法】
【常用十大算法_动态规划算法(DP)】
【常用十大算法_KMP算法】
【常用十大算法_普里姆(prim)算法,克鲁斯卡尔(Kruskal)算法】
【常用十大算法_回溯算法】
【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)