この章の内容は、JavaのGithubコードウェアハウスに実装されています:https ://github.com/ZhekaiLi/Code/tree/main/Graph/src
記事の写真を表示するには、科学的なインターネットアクセスが必要になる場合があります。githubを使用して画像を管理しているため、ロードできない状況が発生した場合は、壁を裏返してください
[参照]imoocMr. Bobo:楽しいアルゴリズムシリーズ-インタビューとプロモーションのためのグラフ理論の要点(Java版)
[以前のブログへのリンク]
グラフ理論アルゴリズム(1、2):グラフの分類、グラフの基本概念(無向グラフと有向グラフ、重み付けされていないグラフ、非循環グラフ、完全なグラフ、二者間グラフ、単純なグラフ、接続されたグラフコンポーネント、スパングラフ、サブグラフ、親グラフのツリー)
グラフ理論アルゴリズム(3):グラフの基本表現(隣接行列、隣接リスト、隣接行列と隣接リストの比較)
グラフ理論アルゴリズム(4):グラフの最初の深さトラバーサルDFS
グラフ理論アルゴリズム(5):グラフ幅ファーストトラバーサルBFS
グラフ理論アルゴリズム(6):LeetCodeグラフ理論アルゴリズム演習(785.二者間グラフの判断、695。島の最大面積、フラッドフィルアルゴリズム、ユニオンチェック)
5.グラフBFSの幅優先探索
まず、ツリーの幅優先探索を見てみましょう。次の図は、キューを使用してツリーのBFSを実行する一般的なプロセスを示しています。
bfs(root); // 从根结点开始遍历
bfs(TreeNode node)
queue.add(node);
while(!queue.isEmpty)
v = queue.remove();
list.add(v);
for(w: v.son())
queue.add(w)
グラフの幅優先探索は、ノードwが訪問されたかどうかの判断をqueue.add(w)
前です。時間計算量もO(V + E)O(V + E)です。O (V+E )
javaの実装:GraphBFS.java
DFSで解決できる問題のほとんどは、BFSでも解決できます。
5.1例:2点間のパスを見つける
同様にセクション4.2
pre[0...V-1] = -1;
s = 0; // 自定义的起始点
t = 5; // 自定义的终止点
bfs(s); // 从根结点开始遍历
bfs(int v)
queue.add(v);
pre[v] = v;
while(!queue.isEmpty)
v = queue.pop();
list.add(v);
for(w: v.son())
queue.add(w);
pre[w] = v;
javaの実装:SingleSourcePathBFS.java
5.2プロパティ:重み付けされていないグラフの最短経路
同じことが0→60\to6からです0→6. BFSのパスはDFSのパスよりも短いです。このプロパティは任意のポイントにも適用されます。つまり、BFSは任意のポイントとルートノードの間の最短パスを見つけることができます。
これは、BFSが、ルートノードから始まり、近くから遠くまでトラバースするレイヤーオーダートラバーサルであり、各トラバーサルが最も近いノードを探すためです(エッジに重みが含まれていない場合、欲張りアルゴリズムとして理解できます。 =最も優れている)
トラバーサルプロセス中に距離情報が直接記録される場合dis[]
、ルートノードから任意のノードまでの最短距離を直接読み取ることができます。
javaの実装:USSSPath.java
5.3比較:DFSとBFS
BFSとDFS(非再帰的)を比較すると、唯一の違いは、DFSがスタックを使用し、BFSがキューを使用することです(ノードの処理時にDFSのヘッドインとヘッドアウト、BFSのテールインとヘッドアウト)(statck.add(s)
対応するstack.push()
、statck.remove()
対応するstack.pop()
)
さらに、任意の構造を使用して上記の図を置き換え、カスタムトラバーサル方法stack/ queue
をます。
たとえば、ランダムコンテナ(ランダムキュー)を使用して、エッジへのランダムアクセスによってランダム迷路を生成できます
大きくて見栄えの良い例: