免責事項:この記事はブロガーオリジナル記事です、続く
BY-SAのCC 4.0を
著作権契約、複製、元のソースのリンクと、この文を添付してください。
まず、深さ優先探索紹介
図の深さ優先探索(深さ優先探索)、および比較的類似一次ツリートラバーサル。
考えています:すべての頂点を描画された初期状態を仮定するまで、各未訪問の深さ優先探索グラフトラバーサルからその隣人に続く頂点v、頂点への最初のアクセスから始まる、訪問されていません図の頂点vは、すべての通信パスがアクセス可能である必要があります。この方法は、他の頂点へのアクセス権を持っていない場合、頂点は、代替的出発点として、それは、アクセスされるまで、すべての頂点が描画されるまで処理を繰り返す、アクセスされていません。
明らかに、深さ優先探索は、再帰的なプロセスです。
第二に、深さ優先探索のイラスト
1つの無向グラフ深さ優先探索
深さ優先探索を示すために、一例として、「無向グラフ」に続き。
深さ優先トラバーサルの上のグラフG1は頂点Aから始まり
- ステップ1:A.をご覧ください
- ステップ2:C.アクセス(A点に隣接します)最初のステップ訪問した後、次の訪問は、すなわち、「C、D、F」一点に隣接しなければなりません。しかしながら、本明細書の実装では、頂点は「D及びF」の前で順ABCDEFG、Cに格納され、及びC.すること、アクセス
- ステップ3:アクセス(C隣接点)B. 第二段階C訪問した後、次の訪問は、C、即ち、「BとD」を、点に隣接であるべきである(Aがアクセスされた、それが含まれていません)。そして、理由はB Dの前に、最初の訪問のB.
- ステップ4:アクセス(C隣接点)D. アクセスポイントB C Aに隣接したステップ3の後、無未訪問の隣人B;従って、Cは別のDに隣接しているアクセスポイントに戻ります
- ステップ5:F.アクセス(A点に隣接します)「隣接する全ての隣接点が(内側再帰近隣含む)AにBを指すように、」Aは既に訪問されており、アクセスが終了し、アクセスポイントAに戻ったとき、したがって、別のFに隣接しています
- ステップ6:アクセス(F隣接点)G.
- ステップ7:アクセス(当接点G)E.
こうしてアクセスシーケンスである:A - > C - > B - > D - > F. - > G - > E
有向グラフの2深さ優先探索
例として、「有向グラフ」の下に、深さ優先探索を実証します。
深さ優先トラバーサルの上のグラフG2は、頂点Aから始まり
- ステップ1:A.をご覧ください
- ステップ2:アクセスB. Aを訪問した後、次にアクセスされるべき側の別の頂点、すなわち、頂点Bです。
- ステップ3:アクセスC. Bを訪問した後、次にアクセスされるべきであり、エッジの別の頂点B、すなわち頂点C、E、F。図は、本明細書で実施、順番に格納された頂点ABCDEFG、第1のアクセスC.
- ステップ4:アクセスE. 次のエッジの頂点Cに、さらにアクセス、すなわち頂点E.
- ステップ5:D.をご覧ください 次に、別の頂点Eは、エッジ、すなわち頂点B、Dをアクセスします 頂点Bにアクセスするため、頂点Dにアクセスされています
- ステップ6:F.をご覧ください それは引き継ぐために戻ってする必要があります「別の頂点Fのアクセスの側面を。」
- ステップ7:アクセスG.
因此访问顺序是:A -> B -> C -> E -> D -> F -> G
三、代码实现
-
private boolean[] isVisited = new boolean[vertextSize];
-
-
/**
-
* 获取指定顶点的第一个邻接点
-
*
-
* @param index
-
* 指定邻接点
-
* @return
-
*/
-
private int getFirstNeighbor(int index) {
-
for (int i = 0; i < vertexSize; i++) {
-
if (matrix[index][i] < MAX_WEIGHT && matrix[index][i] > 0) {
-
return i;
-
}
-
}
-
return -1;
-
}
-
-
/**
-
* 获取指定顶点的下一个邻接点
-
*
-
* @param v
-
* 指定的顶点
-
* @param index
-
* 从哪个邻接点开始
-
* @return
-
*/
-
private int getNextNeighbor(int v, int index) {
-
for (int i = index+1; i < vertexSize; i++) {
-
if (matrix[v][i] < MAX_WEIGHT && matrix[v][i] > 0) {
-
return i;
-
}
-
}
-
return -1;
-
}
-
-
/**
-
* 图的深度优先遍历算法
-
*/
-
private void depthFirstSearch(int i) {
-
isVisited[i] = true;
-
int w = getFirstNeighbor(i);
-
while (w != -1) {
-
if (!isVisited[w]) {
-
// 需要遍历该顶点
-
System.out.println("访问到了:" + w + "顶点");
-
depthFirstSearch(w); // 进行深度遍历
-
}
-
w = getNextNeighbor(i, w); // 第一个相对于w的邻接点
-
}
-
}
- 传
0
进去,表示v0
。 - 设置
v0
已访问过,获取v0
的第一个邻接点。w != -1
说明有这个邻接点,然后对这个临界点进行判断。- 已访问,那就找下一个临界点
- 未访问,进行访问,然后对该邻接点进行深度优先遍历。
四、总结
- 遍历规则:不断的沿着顶点的深度方向遍历。顶点的深度方向是指它的邻接点方向。
- 它从图中某个顶点v出发,访问此顶点,然后从顶点的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到。
- 简单说,就是顶点将第一个邻接点当作左孩子,其它邻接点都当做右孩子。最后排成一棵树。
- 深度优先遍历是指先遍历到最深层次,然后再探索邻接点,接着又遍历最深层次。二叉树的先序遍历就是一种深度优先遍历。
我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!
参考资料: