构建最短路径迪杰斯特拉算法和弗洛伊德算法

  解决有向带权图最短路径问题,选用迪杰斯特拉算法和普利姆算法。

  迪杰斯特拉算法类似普利姆算法,也用到了贪心算法的思想,从局部最优解的全局最优解。是从确定的一点出发确定最小生成树。维护一个 path[] dist[] set[]。

  弗洛伊德算法时间复杂度为O(n^3),可以获得任意一点到另一点的最小路径。需要维护一个 dist[][] 和 path[][]。

 

  迪杰斯特拉算法分析如下:    // 打印最短路径的方法 path[]采用双亲存储结构存了一棵二叉树

  

  void printfPath(int path[], int a){
    // 使用数组模拟 栈
    int Stack[maxSize];
    int top = -1;
    while (path[a] != -1){
      stack[++top] = path[a];
      // 找到自己的父节点
      a = path[a];
    }
    stack[++top] = a;
    // 打印最短路径
    while (top != -1){
      System.out.print("  " + stack[top--]);
    }
  }
  void dijkstra(MGraph g, int v, int dist[], int path[]){
    int set[maxSize];//用于标记是否已经并入
    for (int i = 0; i < g.n; i++){
      dist[i] = g.edges[v][i];
      set[i] = 0;
      if (g.edges[v][i] < INF){
        path[i] = v;
      }else {
        // 没有直接相连时设置为 -1
        path[i] = -1;
      }
    }
    set[v] = 1;
    path[v] = -1;
    int j;
    for(i = 0; i < g.n; i++){
      min = INF;
      // 找出 dist[] 中最小的值并记录下标。(获取局部最优解)
      for(j = 0; j < g.n; j++){
        if (set[j] == 0 && dist[j] < min){
          u = j;
          min = dist[j]
        }
      }
      set[u] = 1;
      // 维护 dist[]
      for (j = 0; j < g.n; j++){
        if (set[j] == 0 && dist[u] + g.edges[u][j] < dist[j]){
          dist[j] = dist[u] + g.edges[u][j];
          path[j] = u;//记录路径         }       }     }   }

 

  弗洛伊德算法思想较简单,就是选择中间点,三重循环遍历。

  

  // 选取中间点
  for (int k = 0; k < g.n; k++){
    // 选择行号
    for(int i = 0; i < g.n; i++){
      // 选择列号
      for(int j = 0; j < g.n; j++){
        if (A[i][j] > A[i][k] + A[k][j]){
          // 记录中间点
          path[i][j] = k;
          A[i][j] = A[i][k] + A[k][j];
        }
      }
    }
  }

 

  

posted @ 2021-12-31 15:13  不要西红柿  阅读(217)  评论(0编辑  收藏  举报