Java 由淺入深帶你掌握圖的遍歷
1.圖的遍歷
從圖中某一頂點出發(fā)訪問圖中其余頂點,且每個頂點僅被訪問一次
圖的遍歷有兩種深度優(yōu)先遍歷DFS、廣度優(yōu)先遍歷BFS
2.深度優(yōu)先遍歷
深度優(yōu)先遍歷以深度為優(yōu)先進行遍歷,簡單來說就是每次走到底。類似于二叉樹的前序遍歷
思路:
1.以某一個頂點為起點進行深度優(yōu)先遍歷,并標(biāo)記該頂點已訪問
2.以該頂點為起點選取任意一條路徑一直遍歷到底,并標(biāo)記訪問過的頂點
3.第2步遍歷到底后回退到上一個頂點,重復(fù)第2步
4.遍歷所有頂點結(jié)束
根據(jù)遍歷思路可知,這是一個遞歸的過程,其實DFS與回溯基本相同。
遍歷:

以此圖為例進行深度優(yōu)先遍歷
static void dfs(int[][] graph,int idx,boolean[]visit) {
int len = graph.length;
//訪問過
if(visit[idx]) return;
//訪問該頂點
System.out.println("V"+idx);
//標(biāo)志頂點
visit[idx] = true;
for(int i = 1;i < len;i++) {
//訪問該頂點相連的所有邊
if(graph[idx][i] == 1) {
//遞歸進行dfs遍歷
dfs(graph, i, visit);
}
}
}
遍歷結(jié)果:
V1
V2
V3
V4
V5
V6
V7
V8
V9
創(chuàng)建圖的代碼:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//頂點數(shù) 以1開始
int n = scanner.nextInt();
int[][] graph = new int[n+1][n+1];
//邊數(shù)
int m = scanner.nextInt();
for(int i = 1;i <= m;i++) {
int v1 = scanner.nextInt();
int v2 = scanner.nextInt();
graph[v1][v2] = 1;
graph[v2][v1] = 1;
}
//標(biāo)記數(shù)組 false表示未訪問過
boolean[] visit = new boolean[n+1];
dfs(graph, 1, visit);
}
3.利用DFS判斷有向圖是否存在環(huán)
思路:遍歷某一個頂點時,如果除了上一個頂點之外,還存在其他相連頂點被訪問過,則必然存在環(huán)
//默認無環(huán)
static boolean flag = false;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//頂點數(shù) 以1開始
int n = scanner.nextInt();
int[][] graph = new int[n+1][n+1];
//邊數(shù)
int m = scanner.nextInt();
for(int i = 1;i <= m;i++) {
int v1 = scanner.nextInt();
int v2 = scanner.nextInt();
graph[v1][v2] = 1;
}
//標(biāo)記數(shù)組 true為訪問過
boolean[] visit = new boolean[n+1];
dfs(graph, 1, visit,1);
if(flag)
System.out.println("有環(huán)");
}
static void dfs(int[][] graph,int idx,boolean[]visit,int parent) {
int len = graph.length;
System.out.println("V"+idx);
//標(biāo)記頂點
visit[idx] = true;
for(int i = 1;i < len;i++) {
//訪問該頂點相連的所有邊
if(graph[idx][i] == 1) {
if( !visit[i] ) {
dfs(graph, i, visit,idx);
}
else if(idx != i) {
flag = true;
}
}
}
}
注意:是有向圖判斷是否存在環(huán),無向圖判斷是否存在環(huán)無意義,因為任意兩個存在路徑的頂點都可以是環(huán)
4.廣度優(yōu)先遍歷
廣度優(yōu)先遍歷是以廣度(寬度)為優(yōu)先進行遍歷。類似于二叉樹的層序遍歷
思路:
1.以某一個頂點為起點進行廣度優(yōu)先遍歷,并標(biāo)記該頂點已訪問
2.訪問所有與該頂點相連且未被訪問過的頂點,并標(biāo)記訪問過的頂點
3.以第2步訪問所得頂點為起點重復(fù)1、2步驟
4.遍歷所有頂點結(jié)束
通過隊列來輔助遍歷,隊列出隊順序即是廣度優(yōu)先遍歷結(jié)果

遍歷

以此圖為例,采用鄰接矩陣的方式創(chuàng)建圖,進行BFS遍歷
static void bfs(int[][] graph) {
int len = graph.length;
//標(biāo)記數(shù)組 false表示未訪問過
boolean[] visit = new boolean[len];
//輔助隊列
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
visit[1] = true;
while(!queue.isEmpty()) {
int num = queue.poll();
System.out.println("V"+num);
//遍歷該頂點所有相連頂點
for(int i = 1;i < len;i++) {
//相連并且沒有被訪問過
if(graph[num][i] == 1 && !visit[i]) {
queue.offer(i);
visit[i] = true;
}
}
}
}
遍歷結(jié)果:
V1
V2
V6
V3
V7
V9
V5
V4
V8
創(chuàng)建圖的代碼
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//頂點數(shù) 以1開始
int n = scanner.nextInt();
int[][] graph = new int[n+1][n+1];
//邊數(shù)
int m = scanner.nextInt();
for(int i = 1;i <= m;i++) {
int v1 = scanner.nextInt();
int v2 = scanner.nextInt();
graph[v1][v2] = 1;
graph[v2][v1] = 1;
}
bfs(graph);
}
到此這篇關(guān)于Java 由淺入深帶你掌握圖的遍歷的文章就介紹到這了,更多相關(guān)Java 圖的遍歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 8 對 ArrayList 元素進行排序的操作方法
Java8提供了多種方式對ArrayList元素進行排序,包括使用Collections.sort()方法、Collections.reverseOrder()實現(xiàn)降序排序、使用Lambda表達式進行自定義排序、使用StreamAPI對ArrayList進行排序及按對象屬性排序,本文通過示例代碼介紹的非常詳細,感興趣的朋友一起看看吧2024-11-11
Mybatis傳單個參數(shù)和<if>標(biāo)簽同時使用的問題及解決方法
這篇文章主要介紹了Mybatis傳單個參數(shù)和<if>標(biāo)簽同時使用的問題及解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-05-05
Java反射之Call stack introspection詳解
這篇文章主要介紹了Java反射之Call stack introspection詳解,具有一定參考價值,需要的朋友可以了解下。2017-11-11
解讀maven項目啟動tomcat不報錯但是啟動不起來,tomcat啟動到警告log4j就停止了
這篇文章主要介紹了maven項目啟動tomcat不報錯但是啟動不起來,tomcat啟動到警告log4j就停止了問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
利用Stream聚合函數(shù)如何對BigDecimal求和
這篇文章主要介紹了利用Stream聚合函數(shù)如何對BigDecimal求和問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
Spring MVC請求參數(shù)與響應(yīng)結(jié)果全局加密和解密詳解
這篇文章主要給大家介紹了關(guān)于Spring MVC請求參數(shù)與響應(yīng)結(jié)果全局加密和解密的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
Spring如何利用@Value注解讀取yml中的map配置
這篇文章主要介紹了Spring如何利用@Value注解讀取yml中的map配置,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02

