レッスンアルゴリズムプログラマ(18) - 共通グラフアルゴリズム:幅優先(BFS)

免責事項:この記事はブロガーオリジナル記事です、続く BY-SAのCC 4.0を 著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/m0_37609579/article/details/100110089

まず、幅優先探索の紹介

また、「BFS」または「幅優先探索」として知られて幅優先探索アルゴリズム(幅優先探索)は、BFSと呼びます。

グラフから頂点v、その後、V、その後、個別にこれらの隣人からその隣人を訪問するために、Vの個別訪問したことがない隣人を訪問し、「最初にアクセスするために行った後のアクセスをクリックしてください:アイデアがありますこの時点での数字は、頂点がアクセスされていない場合は、隣接する頂点は、隣接する頂点ドットフィギュアがアクセスされるまで、全ての頂点が訪問してきた隣人にアクセスされた後にアクセスする前に、別のものを必要としますアクセスまでのすべての頂点が描画されるまで処理を繰り返す、新たな出発点として訪問されていない頂点から選択されます。

換言すれば、幅優先探索は、周辺から遠くに、プロセスの開始点として、図Vのトラバーサルであり、vは順次通信経路および1、2、...頂点の経路長にアクセスしました。

第二に、幅優先探索のイラスト

1. No図の幅優先探索ません

幅優先探索を実証するための一例として、「無向グラフ」に続き。図のG1又は上記の例です。

  1. ステップ1:A.をご覧ください 
  2. ステップ2:C、D、Fにアクセスするために Aへの訪問の後、次の隣接アクセスポイントA. 既に述べたように、本明細書に記載の実施態様では、頂点の順序はC.に、従ってアクセスを「D及びF」の前にC、記憶され、そしてABCDEFG 再仕上げ訪問Cの後、ターンアクセスDで、F. 
  3. ステップ3:順次アクセスB、G. 第2段階のアクセスC、Dの終了後、F、及び順次隣人にアクセスします。当接ポイントF G.アクセス次いで、第1のアクセスポイント隣接B、C、および 
  4. ステップ4:アクセスE. ステップ3エンドアクセスB、Gにおいて、順次隣人にアクセス。唯一Gは、隣り合うアクセスポイントG E.、当接点Eを有します

こうしてアクセスシーケンスである:A - > C - > D - > F. - > B - > G - > E

2.幅優先探索グラフ

幅優先探索を実証するための一例として、「有向グラフ」の下に。図のG2以上の例です。

  1. ステップ1:A.をご覧ください 
  2. ステップ2:アクセスB. 
  3. ステップ3:C、E、Fにアクセスするために Bを訪問した後、次のアクセス別の頂点B側、すなわちC、E、F。既に順次E、Fにアクセスし、Cにアクセスするため、格納された頂点ABCDEFG順序に従って、本明細書の実施態様では、言及 
  4. ステップ4:順次アクセスD、G. C、E、Fへのアクセスが完了した後、次いで、順次、その頂点の反対側にアクセスします。D Eアバットメントの第1のアクセスポイント、およびその後の当接ポイントF G.アクセス、依然としてすべてのC、E、F、シーケンシャルアクセス、C上へのアクセス権を持っている、とのみE、Fによります

こうしてアクセスシーケンスである:A - > B - > C - > E - > F. - > D - > G

第三に、コードの実装

コアコード:

 
  1.  
    /**
  2.  
    * 图的广度优先遍历算法
  3.  
    */
  4.  
    private void boardFirstSearch(int i) {
  5.  
    LinkedList<Integer> queue = new LinkedList<>();
  6.  
    System.out.println("访问到了:" + i + "顶点");
  7.  
    isVisited[i] = true;
  8.  
    queue.add(i);
  9.  
     
  10.  
    while (queue.size() > 0) {
  11.  
    int w = queue.removeFirst().intValue();
  12.  
    int n = getFirstNeighbor(w);
  13.  
    while (n != -1) {
  14.  
    if (!isVisited[n]) {
  15.  
    System.out.println("访问到了:" + n + "顶点");
  16.  
    isVisited[n] = true;
  17.  
    queue.add(n);
  18.  
    }
  19.  
    n = getNextNeighbor(w, n);
  20.  
    }
  21.  
    }
  22.  
    }
 

第四に、DFSおよび図完全なコードBFS

 
  1.  
    import java.util.LinkedList;
  2.  
     
  3.  
    public class Graph {
  4.  
     
  5.  
    private int vertexSize; // 顶点数量
  6.  
    private int[] vertexs; // 顶点数组
  7.  
    private int[][] matrix; // 包含所有顶点的数组
  8.  
    // 路径权重
  9.  
    // 0意味着顶点自己到自己,无意义
  10.  
    // MAX_WEIGHT也意味着到目的顶点不可达
  11.  
    private static final int MAX_WEIGHT = 1000;
  12.  
    private boolean[] isVisited; // 某顶点是否被访问过
  13.  
     
  14.  
    public Graph(int vertextSize) {
  15.  
    this.vertexSize = vertextSize;
  16.  
    matrix = new int[vertextSize][vertextSize];
  17.  
    vertexs = new int[vertextSize];
  18.  
    for (int i = 0; i < vertextSize; i++) {
  19.  
    vertexs[i] = i;
  20.  
    }
  21.  
    isVisited = new boolean[vertextSize];
  22.  
    }
  23.  
     
  24.  
    /**
  25.  
    * 获取指定顶点的第一个邻接点
  26.  
    *
  27.  
    * @param index
  28.  
    * 指定邻接点
  29.  
    * @return
  30.  
    */
  31.  
    private int getFirstNeighbor(int index) {
  32.  
    for (int i = 0; i < vertexSize; i++) {
  33.  
    if (matrix[index][i] < MAX_WEIGHT && matrix[index][i] > 0) {
  34.  
    return i;
  35.  
    }
  36.  
    }
  37.  
    return -1;
  38.  
    }
  39.  
     
  40.  
    /**
  41.  
    * 获取指定顶点的下一个邻接点
  42.  
    *
  43.  
    * @param v
  44.  
    * 指定的顶点
  45.  
    * @param index
  46.  
    * 从哪个邻接点开始
  47.  
    * @return
  48.  
    */
  49.  
    private int getNextNeighbor(int v, int index) {
  50.  
    for (int i = index+1; i < vertexSize; i++) {
  51.  
    if (matrix[v][i] < MAX_WEIGHT && matrix[v][i] > 0) {
  52.  
    return i;
  53.  
    }
  54.  
    }
  55.  
    return -1;
  56.  
    }
  57.  
     
  58.  
    /**
  59.  
    * 图的深度优先遍历算法
  60.  
    */
  61.  
    private void depthFirstSearch(int i) {
  62.  
    isVisited[i] = true;
  63.  
    int w = getFirstNeighbor(i);
  64.  
    while (w != -1) {
  65.  
    if (!isVisited[w]) {
  66.  
    // 需要遍历该顶点
  67.  
    System.out.println("访问到了:" + w + "顶点");
  68.  
    depthFirstSearch(w); // 进行深度遍历
  69.  
    }
  70.  
    w = getNextNeighbor(i, w); // 第一个相对于w的邻接点
  71.  
    }
  72.  
    }
  73.  
     
  74.  
    /**
  75.  
    * 图的广度优先遍历算法
  76.  
    */
  77.  
    private void boardFirstSearch(int i) {
  78.  
    LinkedList<Integer> queue = new LinkedList<>();
  79.  
    System.out.println("访问到了:" + i + "顶点");
  80.  
    isVisited[i] = true;
  81.  
    queue.add(i);
  82.  
     
  83.  
    while (queue.size() > 0) {
  84.  
    int w = queue.removeFirst().intValue();
  85.  
    int n = getFirstNeighbor(w);
  86.  
    while (n != -1) {
  87.  
    if (!isVisited[n]) {
  88.  
    System.out.println("访问到了:" + n + "顶点");
  89.  
    isVisited[n] = true;
  90.  
    queue.add(n);
  91.  
    }
  92.  
    n = getNextNeighbor(w, n);
  93.  
    }
  94.  
    }
  95.  
    }
  96.  
     
  97.  
    public static void main(String[] args) {
  98.  
    Graph graph = new Graph(9);
  99.  
     
  100.  
    // 顶点的矩阵设置
  101.  
    int[] a1 = new int[] { 0, 10, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
  102.  
    int[] a2 = new int[] { 10, 0, 18, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, MAX_WEIGHT, 12 };
  103.  
    int[] a3 = new int[] { MAX_WEIGHT, MAX_WEIGHT, 0, 22, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 8 };
  104.  
    int[] a4 = new int[] { MAX_WEIGHT, MAX_WEIGHT, 22, 0, 20, MAX_WEIGHT, 24, 16, 21 };
  105.  
    //int[] a4 = new int[] { MAX_WEIGHT, MAX_WEIGHT, 22, 0, 20, MAX_WEIGHT, MAX_WEIGHT, 16, 21 };
  106.  
    int[] a5 = new int[] { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 20, 0, 26, MAX_WEIGHT, 7, MAX_WEIGHT };
  107.  
    int[] a6 = new int[] { 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 26, 0, 17, MAX_WEIGHT, MAX_WEIGHT };
  108.  
    int[] a7 = new int[] { MAX_WEIGHT, 16, MAX_WEIGHT, 24, MAX_WEIGHT, 17, 0, 19, MAX_WEIGHT };
  109.  
    //int[] a7 = new int[] { MAX_WEIGHT, 16, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 17, 0, 19, MAX_WEIGHT };
  110.  
    int[] a8 = new int[] { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, 7, MAX_WEIGHT, 19, 0, MAX_WEIGHT };
  111.  
    int[] a9 = new int[] { MAX_WEIGHT, 12, 8, 21, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 0 };
  112.  
     
  113.  
    graph.matrix[0] = a1;
  114.  
    graph.matrix[1] = a2;
  115.  
    graph.matrix[2] = a3;
  116.  
    graph.matrix[3] = a4;
  117.  
    graph.matrix[4] = a5;
  118.  
    graph.matrix[5] = a6;
  119.  
    graph.matrix[6] = a7;
  120.  
    graph.matrix[7] = a8;
  121.  
    graph.matrix[8] = a9;
  122.  
     
  123.  
    graph.depthFirstSearch(0);
  124.  
    //graph.boardFirstSearch(0);
  125.  
    }
  126.  
     
  127.  
    }
 

V.の概要

  • 幅優先トラバーサル表現各層には、次のレベルをトラバースするトラバース
  • のは、考えてみましょう:としv0、隣接する3つのポイントがありますv1 v2 v3
    • 私たちの訪問V0をした後、その後、V1、V2、V3をご覧ください。私たちは、その隣人を通過し、最終的にその隣人からV3を横断からV2、その後、その隣人を横断開始からV1を終えた後。
    • これは、訪問後3人の隣人です。我々はしたいバック隣人トラバース一つずつ来ますこれは私がオーダーをそれらを保存するための容器を使用すると思います。各時間は、頂点を、次いで容器横断ヘッダから除去されます。ここでは、私が思うにLinkedList、それは追加と削除に合うので、。そして、あなたはここにコレクションを横断する必要はありません。
  • 私たちは、頂点の最初のセットを置くことができ、その後while(!queue.isEmpty())、またはwhile(queue.size() > 0)行います。サイクルを開始します。
    • 次いで取り出し、コレクションの最初の頂点に隣接する最初の要素を削除します訪問の頂点、
      • 頂点が訪問されていない場合は、訪問!その後、コレクション内の頂点。
      • 頂点がすでに訪問した場合は、頂点の次の隣人を検索します。

私のマイクロチャネル公共数:アーキテクチャの聖書(ID:gentoo666)、共有Java乾燥、並行性の高いプログラミング、人気のある技術的なチュートリアル、および分散型マイクロサービス・テクノロジー、建築、デザイン、ブロック・チェーン・テクノロジー、人工知能、ビッグデータ、Javaのインタビュー質問だけでなく、最先端の情報とそんなに人気があります。ああ毎日更新!

参考文献:

  1. https://blog.csdn.net/Strive_Y/article/details/81810012
  2. https://www.jianshu.com/p/23b55db1adc0

 

おすすめ

転載: www.cnblogs.com/anymk/p/11521524.html