成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

廣度優(yōu)先,深度優(yōu)先,尋求最短路徑。

bawn / 3317人閱讀

一、應(yīng)用

深度優(yōu)先:是否存在通路,尋找所有解。

廣度優(yōu)先遍歷:尋求最優(yōu)解,尋求最短路徑

1.鄰接矩陣JAVA代碼實(shí)現(xiàn)

鄰接矩陣可以使用一個(gè)二維數(shù)組來(lái)表示

public class GraphTest {

  // 節(jié)點(diǎn)
  public static class Vertex {
    public String name;
    private boolean isVisited;

    public Vertex(String name) {
      this.name = name;
      this.isVisited = false;
    }

    public void displayName() {
      System.out.println("name:" + name);
    }
  }

  // 圖
  public static class Graph {
    // 存節(jié)點(diǎn)數(shù)據(jù)
    private Vertex[] vertices;
    // 矩陣
    private int[][] matrix;
    // 隊(duì)列,用于BFS
    private Queue queue = new LinkedList<>();
    // 棧,用于DFS
    private Stack stack = new Stack<>();

    private Map dependencyMap = new HashMap<>();

    public Graph(Vertex[] vertices, int[][] matrix) {
      this.vertices = vertices;
      this.matrix = matrix;
    }

    // 找到未訪問(wèn)過(guò)的鄰接點(diǎn)
    public List getUnvisitedVertex(int i) {
      List unvisitedVertices = new ArrayList<>();
      for (int j = 0; j < matrix.length; j++) {
        if (matrix[i][j] > 0 && !vertices[j].isVisited) {
          unvisitedVertices.add(j);
        }
      }
      return unvisitedVertices;
    }

    // 廣度優(yōu)先
    public void bfs(int vertex) {
      queue.offer(vertex);

      while (!queue.isEmpty()) {
        int v = queue.poll();
        if (!vertices[v].isVisited) {
          vertices[v].displayName();
          vertices[v].isVisited = true;

          List unvisitedVertices = getUnvisitedVertex(v);
          unvisitedVertices.forEach(uv -> {
            queue.offer(uv);
            dependencyMap.putIfAbsent(uv, v);
          });
        }
      }
    }

    // 深度優(yōu)先
    public void dfs(int vertex) {
      stack.push(vertex);

      while (!stack.isEmpty()) {
        int v = stack.pop();
        if (!vertices[v].isVisited) {
          vertices[v].displayName();
          vertices[v].isVisited = true;

          List unvisitedVertices = getUnvisitedVertex(v);
          unvisitedVertices.forEach(uv -> stack.push(uv));
        }
      }
    }

    // 深度優(yōu)先遞歸實(shí)現(xiàn)
    public void dfsRecursion(int vertex) {
      if (!vertices[vertex].isVisited) {
        vertices[vertex].displayName();
        vertices[vertex].isVisited = true;

        List unvisitedVertices = getUnvisitedVertex(vertex);
        unvisitedVertices.forEach(this::dfsRecursion);
      }
    }

    public void printShortestPath(int start, int end) {
      bfs(start);

      String symbol = "-->";
      StringBuilder sb = new StringBuilder();
      sb.append(vertices[end].name);
      sb.append(symbol);
      while (dependencyMap.get(end) != null) {
        sb.append(vertices[dependencyMap.get(end)].name);
        sb.append(symbol);
        end = dependencyMap.get(end);
      }
      String path = sb.substring(0, sb.lastIndexOf(symbol));
      System.out.println(path);
    }

    public void clear() {
      stack.clear();
      queue.clear();
      dependencyMap.clear();
      for (int i = 0; i < vertices.length; i++) {
        vertices[i].isVisited = false;
      }
    }

  }

  public static void main(String[] args) {
    Vertex[] vertices = {
            new Vertex("v0"),
            new Vertex("v1"),
            new Vertex("v2"),
            new Vertex("v3"),
            new Vertex("v4")
    };

    int[][] matrix = new int[][]{
            {0, 0, 1, 1, 0},
            {0, 0, 1, 0, 1},
            {1, 1, 0, 0, 1},
            {1, 0, 0, 0, 1},
            {0, 1, 1, 1, 0}
    };

    Graph graph = new Graph(vertices, matrix);

    System.out.println("廣度優(yōu)先搜索:");
    graph.bfs(0);
    graph.clear();

    System.out.println("深度優(yōu)先搜索:");

    graph.dfs(0);
    graph.clear();

    System.out.println("遞歸深度優(yōu)先搜索:");

    graph.dfsRecursion(0);
    graph.clear();

    System.out.println("打印最短路徑:");

    graph.printShortestPath(0, 4);
  }
}

打印結(jié)果
廣度優(yōu)先搜索:
name:v0
name:v2
name:v3
name:v1
name:v4
深度優(yōu)先搜索:
name:v0
name:v3
name:v4
name:v2
name:v1
遞歸深度優(yōu)先搜索:
name:v0
name:v2
name:v1
name:v4
name:v3
打印最短路徑:
name:v0
name:v2
name:v3
name:v1
name:v4
v4-->v2-->v0

2.鄰接表JAVA代碼實(shí)現(xiàn)

鄰接表可以使用數(shù)組+鏈表,鏈表+鏈表,哈希表等等數(shù)據(jù)結(jié)構(gòu)來(lái)表示。在java中,map結(jié)構(gòu)非常適合表示鄰接表

public class GraphTest {
  public static void main(String[] args){
    //初始化先建立起各個(gè)節(jié)點(diǎn)信息,以及對(duì)應(yīng)的直接子節(jié)點(diǎn)列表
    HashMap map = new HashMap<>();
    map.put("V0", new String[] {"V2","V3"});
    map.put("V1", new String[] {"V2","V4"});
    map.put("V2", new String[] {"V0","V1","V4"});
    map.put("V3", new String[] {"V0","V4"});
    map.put("V4", new String[] {"V1","V2","V3"});
    //獲取從A到H的最短路徑節(jié)點(diǎn)鏈表
    Node target = findTarget("V0","V4",map);
    //打印出最短路徑的各個(gè)節(jié)點(diǎn)信息
    printSearPath(target);

  }

  /**
   * 打印出到達(dá)節(jié)點(diǎn)target所經(jīng)過(guò)的各個(gè)節(jié)點(diǎn)信息
   * @param target
   */
  static void printSearPath(Node target) {
    if (target != null) {
      System.out.print("找到了目標(biāo)節(jié)點(diǎn):" + target.id + "
");

      List searchPath = new ArrayList();
      searchPath.add(target);
      Node node = target.parent;
      while(node!=null) {
        searchPath.add(node);
        node = node.parent;
      }
      String path = "";
      for(int i=searchPath.size()-1;i>=0;i--) {
        path += searchPath.get(i).id;
        if(i!=0) {
          path += "-->";
        }
      }
      System.out.print("步數(shù)最短:"+path);
    } else {
      System.out.print("未找到了目標(biāo)節(jié)點(diǎn)");
    }
  }

  /**
   * 從指定的開(kāi)始節(jié)點(diǎn) startId ,查詢到目標(biāo)節(jié)點(diǎn)targetId 的最短路徑
   * @param startId
   * @param targetId
   * @param map
   * @return
   */
  static Node findTarget(String startId,String targetId,HashMap map) {
    List hasSearchList = new ArrayList();
    LinkedList queue = new LinkedList();
    queue.offer(new Node(startId,null));
    while(!queue.isEmpty()) {
      Node node = queue.poll();

      if(hasSearchList.contains(node.id)) {
        //跳過(guò)已經(jīng)搜索過(guò)的,避免重復(fù)或者死循環(huán)
        continue;
      }
      System.out.print("判斷節(jié)點(diǎn):" + node.id +"
");
      if (targetId.equals(node.id)) {
        return node;
      }
      hasSearchList.add(node.id);
      if (map.get(node.id) != null && map.get(node.id).length > 0) {
        for (String childId : map.get(node.id)) {
          queue.offer(new Node(childId,node));
        }
      }
    }

    return null;
  }

  /**
   * 節(jié)點(diǎn)對(duì)象
   * @author Administrator
   *
   */
  static class Node{
    //節(jié)點(diǎn)唯一id
    public String id;
    //該節(jié)點(diǎn)的直接父節(jié)點(diǎn)
    public Node parent;
    //該節(jié)點(diǎn)的直接子節(jié)點(diǎn)
    public List childs = new ArrayList();
    public Node(String id,Node parent) {
      this.id = id;
      this.parent = parent;
    }
  }
}

打?。?br>判斷節(jié)點(diǎn):V0
判斷節(jié)點(diǎn):V2
判斷節(jié)點(diǎn):V3
判斷節(jié)點(diǎn):V1
判斷節(jié)點(diǎn):V4
找到了目標(biāo)節(jié)點(diǎn):V4
步數(shù)最短:V0-->V2-->V4

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75297.html

相關(guān)文章

  • 算法-圖和圖算法

    摘要:圖的定義用圖對(duì)現(xiàn)實(shí)中的系統(tǒng)建模可以用圖對(duì)現(xiàn)實(shí)中的很多系統(tǒng)建模比如對(duì)交通流量建模頂點(diǎn)可以表示街道的十字路口邊可以表示街道加權(quán)的邊可以表示限速或者車道的數(shù)量建模人員可以用這個(gè)系統(tǒng)來(lái)判斷最佳路線及最有可能堵車的街道任何運(yùn)輸系統(tǒng)都可以用圖來(lái)建模比如 圖的定義 用圖對(duì)現(xiàn)實(shí)中的系統(tǒng)建模 可以用圖對(duì)現(xiàn)實(shí)中的很多系統(tǒng)建模. 比如對(duì)交通流量建模, 頂點(diǎn)可以表示街道的十字路口, 邊可以表示街道. 加權(quán)的邊...

    Anshiii 評(píng)論0 收藏0
  • 圖的JS實(shí)現(xiàn)

    摘要:圖的實(shí)現(xiàn)如下采用鄰接表結(jié)構(gòu)實(shí)現(xiàn)。由于本次示例的是無(wú)向圖,因此每個(gè)頂點(diǎn)都互相增加為鄰接點(diǎn)。然而由于本次示例的圖為無(wú)向圖,會(huì)出現(xiàn)重復(fù)遍歷的情況,例如頂點(diǎn)的鄰接點(diǎn)有,的鄰接點(diǎn)有。 圖的定義 圖就是由若干個(gè)頂點(diǎn)和邊連接起來(lái)的一種結(jié)構(gòu)。很多東西都可以用圖來(lái)說(shuō)明,例如人際關(guān)系,或者地圖。 其中圖還分為有向圖和無(wú)向圖。如下就是有向圖 圖的數(shù)據(jù)結(jié)構(gòu) 對(duì)于圖這種關(guān)系,可以通過(guò)兩種方式來(lái)存儲(chǔ)。 領(lǐng)接表 將...

    LeanCloud 評(píng)論0 收藏0
  • 基于JavaScript求解八數(shù)碼短路并生成動(dòng)畫(huà)效果

    摘要:寫(xiě)在最前本次分享一下通過(guò)廣度優(yōu)先搜索解決八數(shù)碼問(wèn)題并展示其最短路徑的動(dòng)畫(huà)效果。一個(gè)排列中逆序的總數(shù)就稱為這個(gè)排列的逆序數(shù)。如果起始狀態(tài)與結(jié)束狀態(tài)的逆序數(shù)的奇偶性相同,則說(shuō)明狀態(tài)可達(dá),反之亦然。 寫(xiě)在最前 本次分享一下通過(guò)廣度優(yōu)先搜索解決八數(shù)碼問(wèn)題并展示其最短路徑的動(dòng)畫(huà)效果。 歡迎關(guān)注我的博客,不定期更新中—— 效果預(yù)覽 該效果為從[[2, 6, 3],[4, 8, 0],[7, 1, ...

    Jioby 評(píng)論0 收藏0
  • 隊(duì)列和 BFS —— 棧和 DFS

    摘要:隊(duì)列和廣度優(yōu)先搜索的一個(gè)常見(jiàn)應(yīng)用是找出從根結(jié)點(diǎn)到目標(biāo)結(jié)點(diǎn)的最短路徑。然后在每一輪中,我們逐個(gè)處理已經(jīng)在隊(duì)列中的結(jié)點(diǎn),并將所有鄰居添加到隊(duì)列中。這就是我們?cè)谥惺褂藐?duì)列的原因。 隊(duì)列和 BFS: 廣度優(yōu)先搜索(BFS)的一個(gè)常見(jiàn)應(yīng)用是找出從根結(jié)點(diǎn)到目標(biāo)結(jié)點(diǎn)的最短路徑。 示例 這里我們提供一個(gè)示例來(lái)說(shuō)明如何使用 BFS 來(lái)找出根結(jié)點(diǎn) A 和目標(biāo)結(jié)點(diǎn) G 之間的最短路徑。 showImg(h...

    Kyxy 評(píng)論0 收藏0
  • 算法系列——JavaScript中廣度優(yōu)先搜索思想實(shí)現(xiàn)

    摘要:散列表上面的地圖向我們展示了如何用廣度優(yōu)先搜索的思想找到北京到廣州的最短路線。在廣度優(yōu)先搜索中,我們需要用到隊(duì)列的這種思想來(lái)實(shí)現(xiàn)查找。建立了下面這個(gè)模型武漢廣州西藏上海上海武漢廣州代碼完整實(shí)現(xiàn),利用遞歸和廣度優(yōu)先搜索的思想實(shí)現(xiàn)。 什么是廣度優(yōu)先搜索? 如果只是是背概念,幼兒園的小朋友都能背下來(lái)念給你聽(tīng)。 假設(shè)看這篇文章的都和我一樣是個(gè)前端工程師,我們要從廣度優(yōu)先搜索(BFS)中學(xué)到什么...

    everfly 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

bawn

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<