自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

圖算法系列之深度優(yōu)先搜索

開發(fā) 架構(gòu) 算法
在這篇采用的是union-find算法實現(xiàn)的連通性檢查,本篇我們將采用深度優(yōu)先搜索的方式來找出圖中的所有連通分量

[[396433]]

本文轉(zhuǎn)載自微信公眾號「貝塔學JAVA」,作者Silently9527。轉(zhuǎn)載本文請聯(lián)系貝塔學JAVA公眾號。

在上篇中我們學習了深度優(yōu)先搜索,知道了如何通過深度優(yōu)先搜索在圖中尋找路徑;本篇我們繼續(xù)一起來學習深度優(yōu)先搜索算法的其他應用場景

連通分量

從一幅圖中找出所有的連通分量,這是也是深度優(yōu)先搜索的一個應用場景。什么是連通分量?這個定義在之前的文章中已有提到《如何檢測社交網(wǎng)絡中兩個人是否是朋友關系(union-find算法)》

在這篇采用的是union-find算法實現(xiàn)的連通性檢查,本篇我們將采用深度優(yōu)先搜索的方式來找出圖中的所有連通分量

連通分量的API定義

  1. public class DepthFirstCC { 
  2.     public DepthFirstCC(Graph graph);  
  3.      
  4.     public boolean connected(int v, int w); //檢查兩個頂點是否連通 
  5.  
  6.     public int count(); //統(tǒng)計連通分量的總數(shù) 
  7.  
  8.     public int id(int v); //頂點v所在連通分量的標識 

連通分量的API實現(xiàn)

與之前一樣沒掃描到一個頂點我們就需要標記這個頂點,所以依然需要定義一個marked[]數(shù)組

為了統(tǒng)計出圖中總共有多少連通分量,所以需要定義一個變量count

為了判斷兩個頂點是否相連,我們需要把相連的頂點對應的標識值記錄成相同值,當在調(diào)用connected方法的時候直接取出兩個頂點的標識值比較,如果相同就是連通的,否則就是非連通;

這個的標識值我們使用的是count的值,每個頂點都需要存一個標識值,所以還需要一個ids[]數(shù)組。

  1. public class DepthFirstCC { 
  2.     private boolean marked[]; 
  3.     private int count
  4.     private int[] ids; 
  5.  
  6.     public DepthFirstCC(Graph graph) { 
  7.         this.marked = new boolean[graph.V()]; 
  8.         this.ids = new int[graph.V()]; 
  9.  
  10.         for (int v = 0; v < graph.V(); v++) { 
  11.             if (!this.marked[v]) { 
  12.                 dfs(graph, v); 
  13.                 count++; 
  14.             } 
  15.         } 
  16.     } 
  17.  
  18.     private void dfs(Graph graph, int v) { 
  19.         this.marked[v] = true
  20.         this.ids[v] = count
  21.         for (int w : graph.adj(v)) { 
  22.             if (!this.marked[w]) { 
  23.                 dfs(graph, w); 
  24.             } 
  25.         } 
  26.     } 
  27.  
  28.     public boolean connected(int v, int w) { 
  29.         return id(v) == id(w); 
  30.     } 
  31.  
  32.     public int count() { 
  33.         return count
  34.     } 
  35.  
  36.     public int id(int v) { 
  37.         return ids[v]; 
  38.     } 
  39.  

單元測試

構(gòu)造這樣一個圖,連通分量的總數(shù)應該是3

  1. @Test 
  2. public void test() { 
  3.     Graph graph = new Graph(10); 
  4.     graph.addEdge(0, 1); 
  5.     graph.addEdge(0, 2); 
  6.     graph.addEdge(0, 5); 
  7.     graph.addEdge(1, 3); 
  8.     graph.addEdge(2, 4); 
  9.     graph.addEdge(4, 3); 
  10.     graph.addEdge(5, 3); 
  11.  
  12.     graph.addEdge(6, 7); 
  13.  
  14.     graph.addEdge(8, 9); 
  15.  
  16.     DepthFirstCC cc = new DepthFirstCC(graph); 
  17.  
  18.     System.out.println(cc.connected(0,5)); 
  19.     System.out.println(cc.connected(1,2)); 
  20.  
  21.     System.out.println(cc.count()); 

基于深度優(yōu)先搜索實現(xiàn)的連通性檢查理論上說要比以前實現(xiàn)的union-find算法更快,因為檢查連通性深度優(yōu)先搜索實現(xiàn)的版本能夠保證在常量時間內(nèi)完成,而union-find算法不行;

但是union-find也有自己的優(yōu)勢: 不需要把完整的構(gòu)造并表示一張圖,更重要的是union-find算法是動態(tài)的添加節(jié)點。

檢查無向圖中是否有環(huán)

為了減小實現(xiàn)的復雜度,我們假設圖中不存在自環(huán)和平行邊;

假如從頂點v出發(fā)存在環(huán),表示從頂點v出發(fā)的連通分量中某個頂點的鄰接頂點是v,那么在搜索的過程中必定會再次遇到頂點v

實現(xiàn)的思路:

  1. 標記已經(jīng)搜索過的每個頂點
  2. 當遇到了一個已經(jīng)被標記過的頂點,表示已經(jīng)圖中存在環(huán);
  3. 由于圖是無向圖,如果v-w相連,那么頂點v中的鄰接表中有w,w鄰接表中也會有v,但是他們沒有構(gòu)成環(huán),所以需要排除掉該情況。
  1. public class Cycle { 
  2.     private boolean marked[]; 
  3.     private boolean hashCycle; 
  4.  
  5.     public Cycle(Graph graph) { 
  6.         this.marked = new boolean[graph.V()]; 
  7.         for (int s = 0; s < graph.V(); s++) { 
  8.             if (!this.marked[s]) { 
  9.                 dfs(graph, s, s); 
  10.             } 
  11.         } 
  12.     } 
  13.  
  14.     private void dfs(Graph graph, int v, int pV) { 
  15.         this.marked[v] = true
  16.         for (int w : graph.adj(v)) { 
  17.             if (!this.marked[w]) { 
  18.                 this.dfs(graph, w, v); 
  19.             } else if (w != pV) { 
  20.                 this.hashCycle = true
  21.                 return
  22.             } 
  23.         } 
  24.     } 
  25.  
  26.     public boolean hasCycle() { 
  27.         return hashCycle; 
  28.     } 

方法dfs的參數(shù)v表示需要待搜索的頂點,pV表示的是到達v的頂點,所以如果v的鄰接表中有個頂點已被標記過并且該頂點不等于到達v的頂點,那么表示圖中有環(huán)

檢查無向圖是否是二分圖

何為二分圖? 圖中每條邊所連接的頂點都屬于不同的部分;如下圖:

其中紅色節(jié)點表示一個集合,白色節(jié)點是另一個集合,每條邊連接的兩個頂點屬于不同的集合;

舉個實際的例子就很好理解,電影與演員的關系,電影作為一個頂點,演員作為一個頂點,電影與電影直接是不會有邊,演員與演員直接也不會有邊,這就是一張二分圖。

  1. public class TwoColorGraph { 
  2.     private boolean twoColor = true
  3.     private boolean[] marked; 
  4.     private boolean[] color; 
  5.  
  6.     public TwoColorGraph(Graph graph) { 
  7.         this.marked = new boolean[graph.V()]; 
  8.         this.color = new boolean[graph.V()]; 
  9.  
  10.         for (int v = 0; v < graph.V(); v++) { 
  11.             if (!this.marked[v]) { 
  12.                 dfs(graph, v); 
  13.             } 
  14.         } 
  15.     } 
  16.  
  17.     private void dfs(Graph graph, int v) { 
  18.         this.marked[v] = true
  19.         for (int w : graph.adj(v)) { 
  20.             if (!this.marked[w]) { 
  21.                 this.color[w] = !this.color[v]; 
  22.                 dfs(graph, w); 
  23.             } else if (this.color[w] == this.color[v]) { 
  24.                 this.twoColor = false
  25.                 return
  26.             } 
  27.         } 
  28.     } 
  29.  
  30.     public boolean isTwoColor() { 
  31.         return twoColor; 
  32.     } 

 

文中所有源碼已放入到了github倉庫:https://github.com/silently9527/JavaCore

 

責任編輯:武曉燕 來源: 貝塔學JAVA
相關推薦

2025-02-26 05:00:00

DFS算法遞歸

2020-10-17 11:14:19

數(shù)據(jù)結(jié)構(gòu)與算法系列

2023-04-14 08:07:20

數(shù)據(jù)結(jié)構(gòu)算法搜索

2021-04-19 09:08:19

無向圖數(shù)據(jù)結(jié)構(gòu)

2021-05-10 08:07:40

圖算法路徑頂點

2020-09-16 12:23:37

TypeScript

2022-03-25 00:00:00

Splunk搜索SPL

2020-04-16 13:48:27

DFS BFS優(yōu)先遍歷

2017-03-20 13:09:33

Swift廣度優(yōu)先搜索手游開發(fā)

2018-04-04 10:19:32

深度學習

2014-08-13 11:04:02

搜索引擎排序算法

2018-03-26 20:07:25

深度學習

2020-12-16 05:58:43

算法數(shù)據(jù)結(jié)構(gòu)前端

2023-12-19 16:01:40

深度學習人工智能目標檢測

2023-11-06 07:46:22

圖算法數(shù)據(jù)結(jié)構(gòu)

2023-07-19 08:55:00

神經(jīng)網(wǎng)絡推薦系統(tǒng)

2009-02-25 13:59:57

布爾全文搜索全文搜索內(nèi)置函數(shù)

2021-04-16 11:31:24

人工智能深度學習

2022-06-10 07:13:29

JVM垃圾回收

2025-02-05 07:26:45

點贊
收藏

51CTO技術棧公眾號