最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實現(xiàn)單源最短路徑

 更新時間:2019年01月21日 09:02:34   作者:浮生若夢yoo  
這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)單源最短路徑,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文采用java實現(xiàn)單源最短路徑,并帶有略微詳細(xì)的注解,供大家參考,具體內(nèi)容如下

package com.qf.greaph;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author jiayoo
 * 7 / 30 
 * Dijkstra最短路徑算法是一種單源最短路徑
 * 本文采用的是鄰接表表示圖。
 * 
 * 圖的表示: 1. 采用 ArrayList 來儲存 圖的頂點(diǎn)
 *   2. 采用 Map 來儲存 邊集 , map 可以 實現(xiàn) 一對多的關(guān)系, 因此能很好的實現(xiàn)鄰接表結(jié)構(gòu)
 *   3. 采用ArrayList的原因 是使 邊集有序 這樣, Node 的里面 那個記錄距離的集合才能一一對應(yīng)
 */

public class MinPath {

  private static class graph{
    private ArrayList<Node1> nodes = new ArrayList<>(); // 表示圖頂點(diǎn) , 同時他也作為V集合
    private Map<Node1, ArrayList<Node1>> adjaNode = new HashMap<>(); // 表示圖的邊
    private ArrayList<Node1> nodes1 ; // 表示S集合, 即存儲已經(jīng)訪問的節(jié)點(diǎn),
    private float[] minPath; //用來存儲源點(diǎn)到每個頂點(diǎn)的距離
    float min = Float.MAX_VALUE;

    /**
     * @param start
     * @param end
     * @param distance
     * 構(gòu)建鄰接表。使之成為圖
     */
    public void addAdjaNode(Node1 start, Node1 end, float distance) {

      if (!nodes.contains(start)) {
        nodes.add(start);
      }
      if (!nodes.contains(end)) {
        nodes.add(end);
      }
      if (adjaNode.containsKey(start) && adjaNode.get(start).contains(end)) {
        return ;
      }

      if (adjaNode.containsKey(start)) {
        adjaNode.get(start).add(end);
      }else {
        ArrayList<Node1> node = new ArrayList<Node1>();
        node.add(end);
        adjaNode.put(start, node);
      }
      start.distonext.add(distance);
    }

    /**
     * 將圖打印出來
     */
    public void prinGraph() {
      if (nodes == null || adjaNode == null) {
        System.out.println("圖為空");
        return ;
      }

      for (Entry<Node1, ArrayList<Node1>> entry : adjaNode.entrySet()) {
        System.out.println("頂點(diǎn) : " + entry.getKey().name + " 鏈接頂點(diǎn)有: ");
        for(int i = 0; i < entry.getValue().size(); i++) {
          System.out.print(entry.getValue().get(i).name + " " + "距離是: " + entry.getKey().distonext.get(i) + ", ");
        }
        System.out.println();
      }
    }


    /**
     * 1.這個方法用于初始化S集合 及 初始化距離數(shù)組
     * 2. 設(shè)置源點(diǎn), 并且將源點(diǎn)作為內(nèi)容 初始化算法
     */
    public void findMinPath() {
      Node1 node1 = null; // 用來記錄列表里最小的點(diǎn)
      nodes1 = new ArrayList<>(); // 存儲已經(jīng)遍歷過的點(diǎn)
      minPath = new float[nodes.size()]; // 初始化距離數(shù)組
      int i;
      /*
       * 對最短路徑進(jìn)行初始化, 設(shè)置源點(diǎn)到其他地方的值為無窮大
       * */
      for (i = 0; i < minPath.length; i++) {
        minPath[i] = Float.MAX_VALUE;
      }
      Node1 node = nodes.get(0); 
      nodes1.add(node); // 將源點(diǎn)加入 S 集合
      node.visited = true;

      ArrayList<Node1> n = adjaNode.get(node); // 獲取到源點(diǎn)的邊集
      /*
       * 先對源節(jié)點(diǎn)進(jìn)行初始化
       * 1. 對 距離數(shù)組進(jìn)行初始化。
       * 2. 找到源點(diǎn)到某個距離最短的點(diǎn), 并標(biāo)記
       * 
       * */
      for (i = 0; i < n.size(); i++) {
        minPath[n.get(i).id] = node.distonext.get(i); // 最短路徑記錄
        if (min > node.distonext.get(i)) {
          min = node.distonext.get(i);
          node1 = n.get(i); // 找到當(dāng)前最短路徑
        }
      }
      this.process(node1, min);
    }


    private void process(Node1 node, float distance ) {
      min = Float.MAX_VALUE; //作為標(biāo)記
      Node1 node1 = null; // 同樣記錄距離最短的點(diǎn)
      int i;
      ArrayList<Node1> n = adjaNode.get(node); // 獲得邊集
      for (i = 0 ; i < n.size(); i++) {
        if (!n.get(i).visited) { // 這個邊集里的頂點(diǎn)不在 S 集合里
          if (minPath[n.get(i).id] == Float.MAX_VALUE) {
            minPath[n.get(i).id] = distance + node.distonext.get(i); // 源點(diǎn)到下一點(diǎn)的距離
          }else if (distance + node.distonext.get(i) < minPath[n.get(i).id] ) { //源點(diǎn)到該頂點(diǎn)的距離變小了, 則改變
            minPath[n.get(i).id] = distance + node.distonext.get(i); // 更新源點(diǎn)到下一個點(diǎn)的距離
          }
        }
      }
      /*
       * 這個for 用于找到 距離集合中 距離源點(diǎn)最近 且并未被訪問過的
       * 這個for 同時可以確保 該節(jié)點(diǎn)確實可到達(dá)
       * */

      for (i = 1; i < minPath.length; i++) {
        if (!nodes.get(i).visited) {
          if (min  > minPath[i] ) { 
            min = minPath[i];
            node1 = nodes.get(i);
          }
        }
      }
      if (node1 != null) {
        node1.visited = true;
        process(node1, min); //源點(diǎn)到 當(dāng)前的距離
      }else { // 說明此位置沒有后續(xù)節(jié)點(diǎn), 或者 已經(jīng)全部被訪問完了, 則到達(dá)此位置只需要加上此位置的值

      }      
    }
  }

  public static void main(String[] args) {

    Node1 n1 = new Node1(0,"A");
    Node1 n2 = new Node1(1,"B");
    Node1 n3 = new Node1(2,"C");
    Node1 n4 = new Node1(3,"D");
    Node1 n5 = new Node1(4,"E");
    Node1 n6 = new Node1(5,"F");
    graph gp = new graph();
    gp.addAdjaNode(n1, n2, 6);
    gp.addAdjaNode(n2, n1, 6);
    gp.addAdjaNode(n1, n3, 3);
    gp.addAdjaNode(n3, n1, 3);


    gp.addAdjaNode(n2, n3, 2);
    gp.addAdjaNode(n3, n2, 2);
    gp.addAdjaNode(n2, n4, 5);
    gp.addAdjaNode(n4, n2, 5);

    gp.addAdjaNode(n3, n4, 3);
    gp.addAdjaNode(n4, n3, 3);
    gp.addAdjaNode(n3, n5, 4);
    gp.addAdjaNode(n5, n3, 4);

    gp.addAdjaNode(n4, n5, 2);
    gp.addAdjaNode(n5, n4, 2);
    gp.addAdjaNode(n4, n6, 3);
    gp.addAdjaNode(n6, n4, 3);

    gp.addAdjaNode(n5, n6, 5);
    gp.addAdjaNode(n6, n5, 5);

    // 下面嘗試一下非連通圖

//   /**
//    *   權(quán)值: 1
//    *  A -----------B
//    * 權(quán) | *
//    * 值 | *  權(quán)值: 3
//    * 2  |  *
//    *   C-----D
//    * 權(quán)值: 5
//    * 
//    * 
//    * */
//   
//   gp.addAdjaNode(n1, n2, 1);
//   gp.addAdjaNode(n2, n1, 1);
//   
//   gp.addAdjaNode(n1, n3, 2);
//   gp.addAdjaNode(n3, n1, 2);
//   
//   gp.addAdjaNode(n1, n4, 3);
//   gp.addAdjaNode(n4, n1, 3);
//   
//   gp.addAdjaNode(n3, n4, 5);
//   gp.addAdjaNode(n4, n3, 5);
    gp.prinGraph();
    System.out.println("--------------------------------------------------------------------");
    System.out.println("此數(shù)組下標(biāo)代表id,值代表從源點(diǎn)分別到各點(diǎn)的最短距離, A開始的下標(biāo)是0, B、C、D等依次類推, 并且源點(diǎn)默認(rèn)設(shè)置為id為零0的開始");
    gp.findMinPath();  
    System.out.println(Arrays.toString(gp.minPath));

  }

}


/**
 * 頂點(diǎn)類
 */
class Node1{
  String name; 
  boolean visited = false; // 訪問狀態(tài)。有效 減少原算法移除V集合中元素所花費(fèi)的時間
  int id = -1; // 設(shè)置默認(rèn)id為-1
  ArrayList<Float> distonext = new ArrayList<>(); //這一點(diǎn) 到另外每一個點(diǎn)的距離
  public Node1(int id, String name) {
    this.id = id;
    this.name = name;
  }

}


以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • shiro無狀態(tài)web集成的示例代碼

    shiro無狀態(tài)web集成的示例代碼

    本篇文章主要介紹了shiro無狀態(tài)web集成的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java中避免NullPointerException的方法總結(jié)

    Java中避免NullPointerException的方法總結(jié)

    這篇文章主要介紹了Java中避免NullPointerException的方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Java JDBC連接數(shù)據(jù)庫常見操作總結(jié)

    Java JDBC連接數(shù)據(jù)庫常見操作總結(jié)

    這篇文章主要介紹了Java JDBC連接數(shù)據(jù)庫常見操作,結(jié)合實例形式總結(jié)分析了java基于jdbc連接mysql、Oracle數(shù)據(jù)庫及連接池相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • java Callable接口和Future接口創(chuàng)建線程示例詳解

    java Callable接口和Future接口創(chuàng)建線程示例詳解

    這篇文章主要為大家介紹了java Callable接口和Future接口創(chuàng)建線程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Java實現(xiàn)把圖片處理到指定大小的操作方法

    Java實現(xiàn)把圖片處理到指定大小的操作方法

    項目開發(fā)中,經(jīng)常遇到圖片上傳功能,發(fā)現(xiàn)如果圖片比較大時,在查看、預(yù)覽、下載速度會特別慢,考慮到浪費(fèi)流量以及文件服務(wù)器的存儲空間,決定在后端優(yōu)化處理完再上傳,所以本文給大家介紹了使用Java把圖片處理到指定大小的操作方法,需要的朋友可以參考下
    2025-03-03
  • Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解

    Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解

    這篇文章主要介紹了Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解,HashMap的key保留了對實際對象的強(qiáng)引用,這意味著只要HashMap對象不被銷毀,還HashMap的所有key所引用的對象就不會被垃圾回收,需要的朋友可以參考下
    2023-09-09
  • SpringBoot監(jiān)聽器的實現(xiàn)示例

    SpringBoot監(jiān)聽器的實現(xiàn)示例

    在SpringBoot中,你可以使用監(jiān)聽器來響應(yīng)特定的事件,本文主要介紹了SpringBoot監(jiān)聽器的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Eclipse新建項目不可選擇Java Project問題解決方案

    Eclipse新建項目不可選擇Java Project問題解決方案

    這篇文章主要介紹了Eclipse新建項目不可選擇Java Project問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • Java異常處理中同時有finally和return語句的執(zhí)行問題

    Java異常處理中同時有finally和return語句的執(zhí)行問題

    這篇文章主要介紹了Java異常處理中同時有finally和return語句的執(zhí)行問題,首先確定的是一般finally語句都會被執(zhí)行...然后,需要的朋友可以參考下
    2015-11-11
  • Java Set簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    Java Set簡介_動力節(jié)點(diǎn)Java學(xué)院整理

    Set最大的特性就是不允許在其中存放的元素是重復(fù)的。接下來通過本文給大家分享java set常用方法和原理分析,需要的的朋友參考下吧
    2017-05-05

最新評論

五家渠市| 化隆| 文登市| 东平县| 察隅县| 平定县| 岢岚县| 彭阳县| 常宁市| 南陵县| 壶关县| 潼关县| 全椒县| 伊吾县| 洞口县| 岳阳县| 阿拉善左旗| 梓潼县| 辰溪县| 邵东县| 昌图县| 兴宁市| 盘山县| 浮梁县| 灵石县| 高青县| 清镇市| 绥阳县| 苏尼特右旗| 安图县| 治县。| 资源县| 汽车| 东平县| 峡江县| 无极县| 开原市| 句容市| 利津县| 许昌县| 丁青县|