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

匿名 (未验证) 提交于 2019-12-03 00:34:01

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

迪杰斯特拉:

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,为就按记为0     public 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];//把目前查到的最小值赋给min                     k = 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(){ //构造函数来确定栈的大小,默认是10        this(10);     }     StackMySelf(int init) {//构造函数来确定栈的大小         if (init >= 0) {//如果栈的容量大于等于1             maxSize = 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开始,所以加个1           top=i;//恢复top的值           return result;         }   }
 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!