Java 由淺入深帶你掌握?qǐng)D的遍歷
1.圖的遍歷
從圖中某一頂點(diǎn)出發(fā)訪問(wèn)圖中其余頂點(diǎn),且每個(gè)頂點(diǎn)僅被訪問(wèn)一次
圖的遍歷有兩種深度優(yōu)先遍歷DFS、廣度優(yōu)先遍歷BFS
2.深度優(yōu)先遍歷
深度優(yōu)先遍歷以深度為優(yōu)先進(jìn)行遍歷,簡(jiǎn)單來(lái)說(shuō)就是每次走到底。類(lèi)似于二叉樹(shù)的前序遍歷
思路:
1.以某一個(gè)頂點(diǎn)為起點(diǎn)進(jìn)行深度優(yōu)先遍歷,并標(biāo)記該頂點(diǎn)已訪問(wèn)
2.以該頂點(diǎn)為起點(diǎn)選取任意一條路徑一直遍歷到底,并標(biāo)記訪問(wèn)過(guò)的頂點(diǎn)
3.第2步遍歷到底后回退到上一個(gè)頂點(diǎn),重復(fù)第2步
4.遍歷所有頂點(diǎn)結(jié)束
根據(jù)遍歷思路可知,這是一個(gè)遞歸的過(guò)程,其實(shí)DFS與回溯基本相同。
遍歷:
以此圖為例進(jìn)行深度優(yōu)先遍歷
static void dfs(int[][] graph,int idx,boolean[]visit) { int len = graph.length; //訪問(wèn)過(guò) if(visit[idx]) return; //訪問(wèn)該頂點(diǎn) System.out.println("V"+idx); //標(biāo)志頂點(diǎn) visit[idx] = true; for(int i = 1;i < len;i++) { //訪問(wèn)該頂點(diǎn)相連的所有邊 if(graph[idx][i] == 1) { //遞歸進(jìn)行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); //頂點(diǎn)數(shù) 以1開(kāi)始 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表示未訪問(wèn)過(guò) boolean[] visit = new boolean[n+1]; dfs(graph, 1, visit); }
3.利用DFS判斷有向圖是否存在環(huán)
思路:遍歷某一個(gè)頂點(diǎn)時(shí),如果除了上一個(gè)頂點(diǎn)之外,還存在其他相連頂點(diǎn)被訪問(wèn)過(guò),則必然存在環(huán)
//默認(rèn)無(wú)環(huán) static boolean flag = false; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); //頂點(diǎn)數(shù) 以1開(kāi)始 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為訪問(wèn)過(guò) 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)記頂點(diǎn) visit[idx] = true; for(int i = 1;i < len;i++) { //訪問(wèn)該頂點(diǎn)相連的所有邊 if(graph[idx][i] == 1) { if( !visit[i] ) { dfs(graph, i, visit,idx); } else if(idx != i) { flag = true; } } } }
注意:是有向圖判斷是否存在環(huán),無(wú)向圖判斷是否存在環(huán)無(wú)意義,因?yàn)槿我鈨蓚€(gè)存在路徑的頂點(diǎn)都可以是環(huán)
4.廣度優(yōu)先遍歷
廣度優(yōu)先遍歷是以廣度(寬度)為優(yōu)先進(jìn)行遍歷。類(lèi)似于二叉樹(shù)的層序遍歷
思路:
1.以某一個(gè)頂點(diǎn)為起點(diǎn)進(jìn)行廣度優(yōu)先遍歷,并標(biāo)記該頂點(diǎn)已訪問(wèn)
2.訪問(wèn)所有與該頂點(diǎn)相連且未被訪問(wèn)過(guò)的頂點(diǎn),并標(biāo)記訪問(wèn)過(guò)的頂點(diǎn)
3.以第2步訪問(wèn)所得頂點(diǎn)為起點(diǎn)重復(fù)1、2步驟
4.遍歷所有頂點(diǎn)結(jié)束
通過(guò)隊(duì)列來(lái)輔助遍歷,隊(duì)列出隊(duì)順序即是廣度優(yōu)先遍歷結(jié)果
遍歷
以此圖為例,采用鄰接矩陣的方式創(chuàng)建圖,進(jìn)行BFS遍歷
static void bfs(int[][] graph) { int len = graph.length; //標(biāo)記數(shù)組 false表示未訪問(wèn)過(guò) boolean[] visit = new boolean[len]; //輔助隊(duì)列 Queue<Integer> queue = new LinkedList<>(); queue.offer(1); visit[1] = true; while(!queue.isEmpty()) { int num = queue.poll(); System.out.println("V"+num); //遍歷該頂點(diǎn)所有相連頂點(diǎn) for(int i = 1;i < len;i++) { //相連并且沒(méi)有被訪問(wèn)過(guò) 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); //頂點(diǎn)數(shù) 以1開(kāi)始 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 由淺入深帶你掌握?qǐng)D的遍歷的文章就介紹到這了,更多相關(guān)Java 圖的遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringSecurity自動(dòng)登錄流程與實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringSecurity自動(dòng)登錄流程與實(shí)現(xiàn)詳解,所謂的自動(dòng)登錄是在訪問(wèn)鏈接時(shí)瀏覽器自動(dòng)攜帶上了Cookie中的Token交給后端校驗(yàn),如果刪掉了Cookie或者過(guò)期了同樣是需要再次驗(yàn)證的,需要的朋友可以參考下2024-01-01JavaWeb?Servlet技術(shù)及其應(yīng)用實(shí)踐
這篇文章主要介紹了JavaWeb?Servlet技術(shù),Servlet指在服務(wù)器端執(zhí)行的一段Java代碼,可以接收用戶的請(qǐng)求和返回給用戶響應(yīng)結(jié)果,感興趣想要詳細(xì)了解可以參考下文2023-05-05java實(shí)時(shí)監(jiān)控文件行尾內(nèi)容的實(shí)現(xiàn)
這篇文章主要介紹了java實(shí)時(shí)監(jiān)控文件行尾內(nèi)容的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Spring Data Jpa 自動(dòng)生成表結(jié)構(gòu)的方法示例
這篇文章主要介紹了Spring Data Jpa 自動(dòng)生成表結(jié)構(gòu)的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java中新建一個(gè)文件、目錄及路徑操作實(shí)例
這篇文章主要給大家介紹了關(guān)于Java中新建一個(gè)文件、目錄及路徑操作的相關(guān)資料,新建文件、目錄及路徑是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)遇到的一個(gè)需求,本文通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12MyBatis-plus報(bào)錯(cuò)Property ‘sqlSessionFactory‘ or 
這篇文章主要給大家介紹了MyBatis-plus 報(bào)錯(cuò) Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的兩種解決方法,如果遇到相同問(wèn)題的朋友可以參考借鑒一下2023-12-12java實(shí)現(xiàn)圖片文字識(shí)別ocr
這篇文章主要介紹了java實(shí)現(xiàn)圖片文字識(shí)別ocr ,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08