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

Java實(shí)現(xiàn)利用廣度優(yōu)先遍歷(BFS)計(jì)算最短路徑的方法

 更新時(shí)間:2015年04月20日 15:24:06   作者:司青  
這篇文章主要介紹了Java實(shí)現(xiàn)利用廣度優(yōu)先遍歷(BFS)計(jì)算最短路徑的方法,實(shí)例分析了廣度優(yōu)先遍歷算法的原理與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下

本文實(shí)例講述了Java實(shí)現(xiàn)利用廣度優(yōu)先遍歷(BFS)計(jì)算最短路徑的方法。分享給大家供大家參考。具體分析如下:

我們用字符串代表圖的頂點(diǎn)(vertax),來模擬學(xué)校中Classroom, Square, Toilet, Canteen, South Gate, North Gate幾個(gè)地點(diǎn),然后計(jì)算任意兩點(diǎn)之間的最短路徑。

如下圖所示:

如,我想從North Gate去Canteen, 程序的輸出結(jié)果應(yīng)為:

BFS: From [North Gate] to [Canteen]:
North Gate
Square
Canteen

首先定義一個(gè)算法接口Algorithm:

public interface Algorithm {
  /**
   * 執(zhí)行算法
   */
  void perform(Graph g, String sourceVertex);
  /**
   * 得到路徑
   */
  Map<String, String> getPath();
}

然后,定義圖:

/**
 * (無向)圖
 */
public class Graph {
  // 圖的起點(diǎn)
  private String firstVertax;
  // 鄰接表
  private Map<String, List<String>> adj = new HashMap<>();
  // 遍歷算法
  private Algorithm algorithm;
  public Graph(Algorithm algorithm) {
    this.algorithm = algorithm;
  }
  /**
   * 執(zhí)行算法
   */
  public void done() {
    algorithm.perform(this, firstVertax);
  }
  /**
   * 得到從起點(diǎn)到{@code vertex}點(diǎn)的最短路徑
   * @param vertex
   * @return
   */
  public Stack<String> findPathTo(String vertex) {
    Stack<String> stack = new Stack<>();
    stack.add(vertex);
    Map<String, String> path = algorithm.getPath();
    for (String location = path.get(vertex) ; false == location.equals(firstVertax) ; location = path.get(location)) {
      stack.push(location);
    }
    stack.push(firstVertax);
    return stack;
  }
  /**
   * 添加一條邊
   */
  public void addEdge(String fromVertex, String toVertex) {
    if (firstVertax == null) {
      firstVertax = fromVertex;
    }
    adj.get(fromVertex).add(toVertex);
    adj.get(toVertex).add(fromVertex);
  }
  /**
   * 添加一個(gè)頂點(diǎn)
   */
  public void addVertex(String vertex) {
    adj.put(vertex, new ArrayList<>());
  }
  public Map<String, List<String>> getAdj() {
    return adj;
  }
}

這里我們使用策略設(shè)計(jì)模式,將算法與Graph類分離,通過在構(gòu)造Graph對(duì)象時(shí)傳入一個(gè)Algorithm接口的實(shí)現(xiàn)來為Graph選擇遍歷算法。

public Graph(Algorithm algorithm) {
    this.algorithm = algorithm;
  }

無向圖的存儲(chǔ)結(jié)構(gòu)為鄰接表,這里用一個(gè)Map表示鄰接表,map的key是學(xué)校地點(diǎn)(String),value是一個(gè)與該地點(diǎn)相連通的地點(diǎn)表(List<String>)。

// 鄰接表
  private Map<String, List<String>> adj = new HashMap<>();

然后,編寫Algorithm接口的BFS實(shí)現(xiàn):

/**
 * 封裝BFS算法
 */
public class BroadFristSearchAlgorithm implements Algorithm {
  // 保存已經(jīng)訪問過的地點(diǎn)
  private List<String> visitedVertex;
  // 保存最短路徑
  private Map<String, String> path;
  @Override
  public void perform(Graph g, String sourceVertex) {
    if (null == visitedVertex) {
      visitedVertex = new ArrayList<>();
    }
    if (null == path) {
      path = new HashMap<>();
    }
    BFS(g, sourceVertex);
  }
  @Override
  public Map<String, String> getPath() {
    return path;
  }
  private void BFS(Graph g, String sourceVertex) {
    Queue<String> queue = new LinkedList<>();
    // 標(biāo)記起點(diǎn)
    visitedVertex.add(sourceVertex);
    // 起點(diǎn)入列
    queue.add(sourceVertex);
    while (false == queue.isEmpty()) {
      String ver = queue.poll();
      List<String> toBeVisitedVertex = g.getAdj().get(ver);
      for (String v : toBeVisitedVertex) {
        if (false == visitedVertex.contains(v)) {
          visitedVertex.add(v);
          path.put(v, ver);
          queue.add(v);
        }
      }
    }
  }
}

其中,path是Map類型,意為從 value 到 key 的一條路徑。

BFS算法描述:

1. 將起點(diǎn)標(biāo)記為已訪問并放入隊(duì)列。
2. 從隊(duì)列中取出一個(gè)頂點(diǎn),得到與該頂點(diǎn)相通的所有頂點(diǎn)。
3. 遍歷這些頂點(diǎn),先判斷頂點(diǎn)是否已被訪問過,如果否,標(biāo)記該點(diǎn)為已訪問,記錄當(dāng)前路徑,并將當(dāng)前頂點(diǎn)入列。
4. 重復(fù)2、3,直到隊(duì)列為空。

測(cè)試用例:

String[] vertex = {"North Gate", "South Gate", "Classroom", "Square", "Toilet", "Canteen"};
  Edge[] edges = {
      new Edge("North Gate", "Classroom"),
      new Edge("North Gate", "Square"),
      new Edge("Classroom", "Toilet"),
      new Edge("Square", "Toilet"),
      new Edge("Square", "Canteen"),
      new Edge("Toilet", "South Gate"),
      new Edge("Toilet", "South Gate"),
  };
@Test
  public void testBFS() {
    Graph g = new Graph(new BroadFristSearchAlgorithm());
    addVertex(g);
    addEdge(g);
    g.done();
    Stack<String> result = g.findPathTo("Canteen");
    System.out.println("BFS: From [North Gate] to [Canteen]:");
    while (!result.isEmpty()) {
      System.out.println(result.pop());
    }
  }

希望本文所述對(duì)大家的java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 用GUI實(shí)現(xiàn)java版貪吃蛇小游戲

    用GUI實(shí)現(xiàn)java版貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了用GUI實(shí)現(xiàn)java版貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Spring MVC文件上傳大小和類型限制以及超大文件上傳bug問題

    Spring MVC文件上傳大小和類型限制以及超大文件上傳bug問題

    這篇文章主要介紹了Spring MVC文件上傳大小和類型限制以及超大文件上傳bug問題,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-10-10
  • Java創(chuàng)建和啟動(dòng)線程的兩種方式實(shí)例分析

    Java創(chuàng)建和啟動(dòng)線程的兩種方式實(shí)例分析

    這篇文章主要介紹了Java創(chuàng)建和啟動(dòng)線程的兩種方式,結(jié)合實(shí)例形式分析了java多線程創(chuàng)建、使用相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • 一文帶你弄懂Java中線程池的原理

    一文帶你弄懂Java中線程池的原理

    工作中,我們經(jīng)常使用線程池,但是你真的了解線程池的原理嗎?同時(shí),線程池工作原理和底層實(shí)現(xiàn)原理也是面試經(jīng)常問的考題,所以,今天我們一起聊聊線程池的原理吧
    2022-12-12
  • 詳細(xì)分析java 動(dòng)態(tài)代理

    詳細(xì)分析java 動(dòng)態(tài)代理

    這篇文章主要介紹了java 動(dòng)態(tài)代理的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java并發(fā)編程中的ReentrantLock類詳解

    Java并發(fā)編程中的ReentrantLock類詳解

    這篇文章主要介紹了Java并發(fā)編程中的ReentrantLock類詳解,ReentrantLock是juc.locks包中的一個(gè)獨(dú)占式可重入鎖,相比synchronized,它可以創(chuàng)建多個(gè)條件等待隊(duì)列,還支持公平/非公平鎖、可中斷、超時(shí)、輪詢等特性,需要的朋友可以參考下
    2023-12-12
  • JAVA 注解詳解及簡(jiǎn)單實(shí)例

    JAVA 注解詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了JAVA 注解詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 通過Session案例分析一次性驗(yàn)證碼登錄

    通過Session案例分析一次性驗(yàn)證碼登錄

    這篇文章主要介紹了通過Session案例分析一次性驗(yàn)證碼登錄,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • Spring?AI?+?混元帶你實(shí)現(xiàn)企業(yè)級(jí)穩(wěn)定可部署的AI業(yè)務(wù)智能體

    Spring?AI?+?混元帶你實(shí)現(xiàn)企業(yè)級(jí)穩(wěn)定可部署的AI業(yè)務(wù)智能體

    我們深入探討了Spring?AI在智能體構(gòu)建中的實(shí)際應(yīng)用,特別是在企業(yè)環(huán)境中的價(jià)值與效能,通過逐步實(shí)現(xiàn)一個(gè)本地部署的智能體解決方案,我們不僅展示了Spring?AI的靈活性與易用性,還強(qiáng)調(diào)了它在推動(dòng)AI技術(shù)與業(yè)務(wù)深度融合方面的潛力,感興趣的朋友一起看看吧
    2024-11-11
  • java實(shí)現(xiàn)分布式鎖的常用三種方式

    java實(shí)現(xiàn)分布式鎖的常用三種方式

    本文主要介紹了java實(shí)現(xiàn)分布式鎖,一般有這3種方式,基于數(shù)據(jù)庫實(shí)現(xiàn)的分布式鎖、基于Redis實(shí)現(xiàn)的分布式鎖和基于Zookeeper實(shí)現(xiàn)的分布式鎖,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08

最新評(píng)論

汉中市| 万盛区| 高唐县| 雅江县| 广水市| 安乡县| 齐齐哈尔市| 安顺市| 上高县| 通渭县| 白朗县| 漳州市| 清流县| 绥化市| 曲阜市| 奉新县| 昌邑市| 镇雄县| 大丰市| 阳信县| 阿合奇县| 隆尧县| 特克斯县| 稷山县| 始兴县| 东方市| 松潘县| 顺义区| 枣阳市| 将乐县| 罗城| 兴山县| 新密市| 天水市| 饶阳县| 互助| 龙州县| 浦县| 广西| 都兰县| 景洪市|