今天学习了这两种算法,都是用来求最小路径的算法,但是迪杰斯特拉算法只能从某个特定点到所有点的最短路径,而佛洛依德算法可以查出任意点到任意点的最小路径。

迪杰斯特拉:

package dijkstra;import java.util.Scanner;
import java.util.Stack;/*
* 算法思路:通过从特定起点查找,一直查找到所有点到这个点的最小路径。
* 算法特点:因为要预防两点间的距离可能不是直接距离最短,所以处理要有些特别
* 算法处理思路:首先通过一个大的循环嵌套循环count(点)-1次,这么做是为了查找除了自身的所有点到起点的权值。
*              再通过一个for循环查找此时可达路径离起点到最近的点。把查出来点的设为已查找过。
*              接下来再通过这个最短权值的点进行for循环操作,这个for循环作用是如果经过新增v
*              顶点到达的定点比当前已知路径都短,我们更新
*              这个路径权值,并设置到这个点的前驱节点是v,让我们查询时能查出路径
*每个点都会走一次
* */
public class Dijkstra {public static void main(String[] args) {DijkstraArithmetic dijkstraArithmetic=new DijkstraArithmetic();dijkstraArithmetic.dijkstra();dijkstraArithmetic.find();}
}class DijkstraArithmetic{//第一步:先准备一个图:final int max = 65535;int[][] graph = new int[][]{{0, 1, 5, max, max, max, max, max, max},{1, 0, 3, 7, 5, max, max, max, max},{5, 3, 0, max, 1, 7, max, max, max},{max, 7, max, 0, 2, max, 3, max, max},{max, 5, 1, 2, 0, 3, 6, 9, max},{max, max, 7, max, 3, 0, max, 5, max},{max, max, max, 3, 6, max, 0, 2, 7},{max, max, max, max, 9, 5, 2, 0, 4},{max, max, max, max, max, max, 7, 4, 0}};int[] D = new int[9]; //建立一个存储起点vo到各点的权值的数组int[] P = new int[9];//建立一个起点到这个点的最短路径的前驱结点int[] fin = new int[9];//建立一个确认每个点是否已经被算出最短路径,以便确认它不需要被再计算,被计算过就被记为1,为就按记为0public void dijkstra() {/***      算法第一步:初始化工作*/int i, j, k=0;//初始化这三个数组,for (i = 0; i < 9; i++) {D[i] = graph[0][i];//初始化权值P[i] = 0;//初始化前驱节点,试试自己的猜想(不行,如果这样的话,后面的!=0判断会出错误,而且能联通的都不为零)fin[i] = 0;}fin[0] = 1;//不用计算起点/** 第二步,通过现可达点查找最小的权值* */for (i = 1; i < 9; i++) {//遍历所有点的个数(除了v0)int min = 65535;for (j = 1; j < 9; j++) {//寻找v0最近的顶点if (fin[j] != 1 && D[j] < min) {//确认要加入的点没有被加入过,并且某点可达且找出最小值min = D[j];//把目前查到的最小值赋给mink = j;//记录最小值的下标}}fin[k] = 1;for (j = 0; j < 9; j++) {//新更新了点,所以有了新的可达路径,更新这些新路径if (fin[j] != 1 && D[j]>min +graph[k][j]){//更新那些和vo没链接但是和新的点有连接的点或者经过新的点有更近路径的点D[j]=min+graph[k][j];//更新D[]数组的最小距离P[j]=k;//设置修正权值的点的前驱结点}}}}public  void find(){//输出最近距离节点int i;System.out.println("请输入你想要到达的结点");Scanner sc=new Scanner(System.in);int pointnum=sc.nextInt();i=pointnum;
//        while(P[i]!=0){//循环输出每个点的前驱
//           System.out.print(P[i]+"<-");
//           i=P[i];
//        }
//        System.out.println("0");//输出最后一个是零点//输出时存的是某个节点的前驱结点//用栈输出StackMySelf stackMySelf=new StackMySelf(15);while(P[i]!=0){System.out.println(P[i]);stackMySelf.push(P[i]);//让每个元素入栈i=P[i];}stackMySelf.push(0);//把起点放进去while(!stackMySelf.empty()){System.out.print(stackMySelf.pop());if(!stackMySelf.empty()){System.out.print("->");//最后一个点后面不会输出->}}}
}class StackMySelf {//自定义一个栈private Object[] data =null;// 先自定义数组来当作栈的容器private int maxSize;//定义栈的最大存储空间private int top=-1;//定义栈的栈顶指针StackMySelf(){ //构造函数来确定栈的大小,默认是10this(10);}StackMySelf(int init) {//构造函数来确定栈的大小if (init >= 0) {//如果栈的容量大于等于1maxSize = init;//确定最大长度data = new Object[init];//实例化数组top = -1;//确认栈顶指针} else {throw new RuntimeException("初始化大小不能小于0" + init);}}public boolean empty(){//判空return top==-1?true:false;}public Object pop() {//出栈if (top == -1) { //先判断栈不为空throw new RuntimeException("栈为空");} else {return data[top--];}}public boolean push(Object e){//入栈if (top == maxSize - 1) {throw new RuntimeException("栈已满");} else {data[++top]=e;//赋值return  true;}}public Object peek(){//查看栈顶元素但不移除if (top == maxSize - 1) {throw new RuntimeException("栈已满");} else {return  data[top];}}public int search(Object e){//返回对象在堆栈中的位置,以1为基数int i=top;//保留top的原本值while(top!=-1){//循环一直找到栈底if(peek()!=e){top--;}else {break;}}int result=top+1;//以1开始,所以加个1top=i;//恢复top的值return result;}}/*
* 算法思路:通过从特定起点查找,一直查找到所有点到这个点的最小路径。
* 算法特点:因为要预防两点间的距离可能不是直接距离最短,所以处理要有些特别
* 算法处理思路:首先通过一个大的循环嵌套循环count(点)-1次,这么做是为了查找除了自身的所有点到起点的权值。
*              再通过一个for循环查找此时可达路径离起点最近的点。把查出来点的设为已查找过。
*              接下来再通过这个最短权值的点进行for循环操作,这个for循环作用是如果经过新增v顶点到达的定点比当前已知路径都短,我们更新
*              这个路径权值,并设置到这个点的前驱节点是v,让我们查询时能查出路径
*每个点都会走一次
* */
public class Dijkstra {public static void main(String[] args) {DijkstraArithmetic dijkstraArithmetic=new DijkstraArithmetic();dijkstraArithmetic.dijkstra();dijkstraArithmetic.find();}
}class DijkstraArithmetic{//第一步:先准备一个图:final int max = 65535;int[][] graph = new int[][]{{0, 1, 5, max, max, max, max, max, max},{1, 0, 3, 7, 5, max, max, max, max},{5, 3, 0, max, 1, 7, max, max, max},{max, 7, max, 0, 2, max, 3, max, max},{max, 5, 1, 2, 0, 3, 6, 9, max},{max, max, 7, max, 3, 0, max, 5, max},{max, max, max, 3, 6, max, 0, 2, 7},{max, max, max, max, 9, 5, 2, 0, 4},{max, max, max, max, max, max, 7, 4, 0}};int[] D = new int[9]; //建立一个存储起点vo到各点的权值的数组int[] P = new int[9];//建立一个起点到这个点的最短路径的前驱结点int[] fin = new int[9];//建立一个确认每个点是否已经被算出最短路径,以便确认它不需要被再计算,被计算过就被记为1,为就按记为0public void dijkstra() {/***      算法第一步:初始化工作*/int i, j, k=0;//初始化这三个数组,for (i = 0; i < 9; i++) {D[i] = graph[0][i];//初始化权值P[i] = 0;//初始化前驱节点,试试自己的猜想(不行,如果这样的话,后面的!=0判断会出错误,而且能联通的都不为零)fin[i] = 0;}fin[0] = 1;//不用计算起点/** 第二步,通过现可达点查找最小的权值* */for (i = 1; i < 9; i++) {//遍历所有点的个数(除了v0)int min = 65535;for (j = 1; j < 9; j++) {//寻找v0最近的顶点if (fin[j] != 1 && D[j] < min) {//确认要加入的点没有被加入过,并且某点可达且找出最小值min = D[j];//把目前查到的最小值赋给mink = j;//记录最小值的下标}}fin[k] = 1;for (j = 0; j < 9; j++) {//新更新了点,所以有了新的可达路径,更新这些新路径if (fin[j] != 1 && D[j]>min +graph[k][j]){//更新那些和vo没链接但是和新的点有连接的点或者经过新的点有更近路径的点D[j]=min+graph[k][j];//更新D[]数组的最小距离P[j]=k;//设置修正权值的点的前驱结点}}}}public  void find(){//输出最近距离节点int i;System.out.println("请输入你想要到达的结点");Scanner sc=new Scanner(System.in);int pointnum=sc.nextInt();i=pointnum;
//        while(P[i]!=0){//循环输出每个点的前驱
//           System.out.print(P[i]+"<-");
//           i=P[i];
//        }
//        System.out.println("0");//输出最后一个是零点//输出时存的是某个节点的前驱结点//用栈输出StackMySelf stackMySelf=new StackMySelf(15);while(P[i]!=0){System.out.println(P[i]);stackMySelf.push(P[i]);//让每个元素入栈i=P[i];}stackMySelf.push(0);//把起点放进去while(!stackMySelf.empty()){System.out.print(stackMySelf.pop());if(!stackMySelf.empty()){System.out.print("->");//最后一个点后面不会输出->}}}
}class StackMySelf {//自定义一个栈private Object[] data =null;// 先自定义数组来当作栈的容器private int maxSize;//定义栈的最大存储空间private int top=-1;//定义栈的栈顶指针StackMySelf(){ //构造函数来确定栈的大小,默认是10this(10);}StackMySelf(int init) {//构造函数来确定栈的大小if (init >= 0) {//如果栈的容量大于等于1maxSize = init;//确定最大长度data = new Object[init];//实例化数组top = -1;//确认栈顶指针} else {throw new RuntimeException("初始化大小不能小于0" + init);}}public boolean empty(){//判空return top==-1?true:false;}public Object pop() {//出栈if (top == -1) { //先判断栈不为空throw new RuntimeException("栈为空");} else {return data[top--];}}public boolean push(Object e){//入栈if (top == maxSize - 1) {throw new RuntimeException("栈已满");} else {data[++top]=e;//赋值return  true;}}public Object peek(){//查看栈顶元素但不移除if (top == maxSize - 1) {throw new RuntimeException("栈已满");} else {return  data[top];}}public int search(Object e){//返回对象在堆栈中的位置,以1为基数int i=top;//保留top的原本值while(top!=-1){//循环一直找到栈底if(peek()!=e){top--;}else {break;}}int result=top+1;//以1开始,所以加个1top=i;//恢复top的值return result;}}

我在这里记下学习这个算法时一些遇到的问题:

如:

如果走到了B更新了B,然后修正到c的路径,可是a从d走才是最近的,这里想了很久,最后发现,他每次循环直走一个点,并设置一个点为走过路径,也就是说修正a到c的路径时,但是并没有把c加入走过路径,这时再通过D数组里的最小值会找到d,然后修正从d走a到c的路径。如果说a先到b直接到c这种情况只可能a到d的路径比a到b到c的路径大。

佛洛依德算法:

package Prim;import com.sun.corba.se.impl.orbutil.graph.Graph;
import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;public class Prim {public static void main(String[] args){int[][] graph=new int[][]{{0,6,1,5,65535,65535},{6,0,5,65535,3,65535},{1,5,0,5,6,4},{5,0,5,0,65535,2},{65535,3,6,65535,0,6},{65535,65535,4,2,6,0}};MinTree minTree=new MinTree();minTree.createMinTree(graph);}}class MinTree{public void createMinTree(int[][] graph) {int i, j,k=0 ,m;int[] lowcost = new int[6];//建立一个存储已被包入当前生成树的所有可达路径的权值int[] adjvex = new int[6];//用来记录可达路径权值的起始点,用于输出路径//接下来初始化第一个点lowcost[0] = 0;//我们要将所有访问过的节点包括设为0,以至于不会被访问到adjvex[0] = 0;//我们设置第一个顶点为0节点//将第一行的数据存入lowcost中for (i = 0; i < 6; i++) {lowcost[i] = graph[0][i];//初始化到所有点的权值,访问不到的是65535,以后会有新的点来更新这个数据adjvex[i] = 0;//先设置所有点都是从vo发出的}/*** 先选出当前可达点的权值最小的点,并加入生成树* **/for (i = 1; i < 6; i++) {//需要连接几个点就遍历几次int min = 65535;//定义在这里防止min拿到了最小值,之后min无法改变for (j = 1; j < 6; j++) {//遍历所有lowcost找到现在最小的权值if (lowcost[j] != 0 && lowcost[j] < min) {min = lowcost[j];//将最小权值点赋给lowcost,循环结束得到最小的k=j;//将最小权值点的下标值存入k}}System.out.println(adjvex[k]+"-"+k);//输出边lowcost[k]=0;//将这个点包入生成树/*** 下面的步骤:* 作用:因为加入了新的节点,所以更新到各个点的最小权值**/for (m=1;m<6;m++){//将新加入生成树的点的连接点的权值全部更新至lowcostif(graph[k][m]!=0&&graph[k][m]<lowcost[m]){//查看这个新加入点的权值是否有小于lowcost存在的权值并存入lowcost[m]=graph[k][m];//赋值adjvex[m]=k;}}}}
}

佛洛依德算法思想就是通过三层循环,把每个点当作中继点,去连接他能连接通的所有点,直到最后一点时,
保证所有点都能有相连接路径,这里有直接连接得也有通过中继点连接的,通过另一个二维数组存储它的路径节点,用于输出。

最短路径算法之迪杰斯特拉算法(Dijkstra)和佛洛依德算法(Floyd)相关推荐

  1. 算法之迪杰斯特拉(dijkstra)非常详细介绍

    迪杰斯特拉(dijkstra)算法是单源最短路径问题的求解方法.单源最短路径就在给出一个固定网络,指定一个原点s,一个目标点e,求这两个点之间的最短路径.举个栗子来理解一下. 小明上学的时候,从家到学 ...

  2. 浅谈迪杰斯特拉(Dijkstra)算法和A*算法原理及实现

    写在前面 最近我在学习一门名叫<智能自主机器人及系统>的课程,虽然跟过去所学的<机器人学>在部分内容上有所重复,但该课程的应用性更强.对于不同的机器人,如差速轮式车.四轮车.四 ...

  3. C++实现迪杰斯特拉(dijkstra)算法(最小生成树)

    迪杰斯特拉(dijkstra)算法是单源最短路径问题的求解方法.参考链接:算法之迪杰斯特拉(dijkstra)非常详细介绍_PRML_MAN的博客-CSDN博客_迪杰斯特拉 使用上面的链接提供的图片进 ...

  4. 最短路径之迪杰斯特拉(Dijkstra 算法)弗洛伊德算法(C语言完整代码实现)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  5. 简述dijkstra算法原理_理解最短路径——迪杰斯特拉(dijkstra)算法

    1.       迪杰斯特拉算法简介 迪杰斯特拉(dijkstra)算法是典型的用来解决最短路径的算法,也是很多教程中的范例,由荷兰计算机科学家狄克斯特拉于1959年提出,用来求得从起始点到其他所有点 ...

  6. Java图结构-模拟校园地图-迪杰斯特拉(Dijkstra)算法求最短路径 #谭子

    目录目录 一.前言 二.模拟校园地图描述 三.分析题目及相关绘图 四.代码部分 1.GraphNode类 2.Menu类(管理文字) 3.Attraction类 4.AttractionGraph类( ...

  7. 最短路径算法-迪杰斯特拉(Dijkstra)

    迪杰斯特拉(Dijkstra) 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径 ...

  8. 六、最短路径——迪杰斯特拉(Dijkstra)算法

    在网图和非网图中,最短路径的含义是不同的.由于非网图它没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径:而对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并 ...

  9. 迪杰斯特拉(Dijkstra)算法之两点之间的最短距离问题

    1.概述 (1)与弗洛伊德(Floyd)算法一样,迪杰斯特拉(Dijkstra)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法,主要特点是以出发点为中心向外层层扩展(广度优先搜索思想),直到扩 ...

最新文章

  1. 手把手教你用anaconda安装pytorch最新版
  2. tensorflow随笔-保存与读取使用模型
  3. 使用Maven archetype 自定义项目脚手架
  4. c语言for循环 wdtcn,MSP430F149的DS18B20C语言程序
  5. 算法 - 排序稳定性总结
  6. 反射获取list泛型_Android 从浅到懂使用反射机制
  7. nginx -- 安装配置Nginx
  8. bzoj千题计划287:bzoj1228: [SDOI2009]ED
  9. [转]Zend Framework + Smarty 应用实例
  10. 数据大屏可视化展示系统有什么作用
  11. c语言用数字定义字符串,c语言怎么定义数字字符串 c语言怎么把数字字符定义字符串...
  12. c语言驾校信息管理系统,驾校综合信息管理系统下载_驾校综合信息管理系统v1.1免费版-这家软件站...
  13. EVO Evaluation of SLAM 4 --- ORB-SLAM3 编译和利用数据集运行
  14. springmvc转换器converter的使用
  15. 在CENTOS 7上安装SNIPE-IT进行资产管理
  16. 使用Intent协议在webview中跳转三方app
  17. 计算机桌面锁屏设置,怎么设置电脑锁屏
  18. ubuntu14.04下推荐的工具及插件
  19. 交互式裁剪系统--2006-Gaze-Based Interaction for Semi-Automatic Photo Cropping
  20. continue / break 跳出指定层循环

热门文章

  1. matlab解矩阵方程组
  2. Android Studio 3.5 打Jar包
  3. 绿芯丨推出智能门锁触摸芯片,助力门锁行业创新
  4. 智能物流配送:未来物流供应链的新模式
  5. manifest.xlm配置错误信息
  6. 考研计算机专业课考研大纲,计算机考研专业课大纲及数一大纲
  7. 会议室预约系统遇到的问题
  8. CPU Utilization is Wrong
  9. 解决Ext.TextField的AllowBlank不能过滤空格代码
  10. 计算机专业大一上学期期末总结