演算法(四)——圖
4.1 圖
關於圖,包括:無向圖(簡單連線)、有向圖(連線有方向性)、加權圖(連線帶有權值)和加權有向圖(連線既有方向性又帶有有權值)。
無向圖
定義:圖是由一組頂點和一組能夠將兩個頂點相連的邊組成的。
- 自環:即一條連線一個頂點和其自身的邊;
- 連線同一對頂點的兩條邊稱為平行邊。
定義:在圖中,路徑是由邊順序連線的一系列頂點。簡單路徑是一條沒有重複頂點的路徑。環是一條至少含有一條邊且起點和終點相同的路徑。簡單環是一條(除了起點和終點必須相同之外)不含有重複頂點和邊的環。路徑或者環的長度為其中所包含的邊數。
定義:如果從任意一個頂點都存在一條路徑到達另一個任意頂點,我們稱這幅圖是連通圖。一幅非連通的圖由若干連通的部分組成,它們都是其極大連通子圖。
定義:樹是一幅無環連通圖。互不相連的樹組成的集合稱為森林。連通圖的生成樹是它的一幅子圖,它含有圖中的所有頂點且是一棵樹。圖的生成樹森林是它的所有連通子樹的生成樹的集合。
4.1.1 表示無向圖的資料型別
要開發處理圖問題的各種演算法,我們首先來看一份定義了圖的基本操作的API。
表4.1.1 無向圖的API
public class Graph | |
Graph(int V) | 建立一個含有V個頂點但不含有邊的圖 |
Graph(In in) | 從標準輸入流in讀入一幅圖 |
int V() | 頂點數 |
int E() | 邊數 |
void addEdge(int v, int w) | 向圖中新增一條邊v-w |
Iterable<Integer> adj(int v) | 和v相鄰的所有頂點 |
String toString() | 物件的字串表示 |
表4.1.2 最常用的圖處理程式碼
任務 | 實現 |
計算v的度數 | public static int degree(Graph G,int v) { int degree = 0; for( int w : G.adj(v) ) degree++; return degree; } |
計算所有頂點的最大度數 | public static int maxDegree(Graph G) { int max = 0; for( int v = 0; v<G.V();v++) if( degree(G,v) >max) max = degree(G,v); return max; } |
計算所有頂點的平均度數 | public static double avgDegree( Graph G ) { return 2.0*G.E( ) / G.v( ); } |
計算自環的個數 | public static int numberOfSelfLoops( Graph G) { int count = 0; for( int v = 0;v<G.V();v++) for(int w:G.adj(v)) if(v==w) count++; return count/2; //每條邊都被記過兩次 } |
圖的鄰接表的字串表示(Graph的例項方法) | public String toString() { String s = V +" vertices, " + E + " edges\n "; for( int v = 0 ;v<V ; v++ ) { s += v +" : "; for( int w :this.adj(v) ) s += w+" "; s += "\n"; } return s; } |
Graph資料型別
public class Graph
{
private final int V; //頂點數目
private int E; //邊的數目
private Bag<Integer>[] adj; //鄰接表
public Graph(int V)
{
this.V = V; this.E = 0;
adj = ( Bag<Integer>[]) new Bag[V]; //建立鄰接表
for(int v = 0; v < V; v++) //將所有連結串列初始化為空
adj[v] = new Bag<Integer>();
}
public Graph(In in)
{
this(in.readInt()); //讀取V並將圖初始化
int E = in.readInt(); //讀取E
for(int i = 0; i < E; i++)
{
int v = in.readInt(); //讀取一個頂點
int w = in.readInt(); //讀取另一個頂點
addEdge(v,w); //新增一條連線它們的邊
}
}
public int V() { return V;}
public int E() { return E;}
public void addEdge( int v , int w )
{
adj[v].add(w); //將w新增到v的連結串列中
adj[w].add(v); //將v新增到w的連結串列中
E++;
}
public Iterable<Integer> adj(int v)
{ return adj[v]; }
}
這份Graph的實現使用了一個由頂點索引的整型連結串列陣列。每條邊都會出現兩次,即當存在一條連線v與w的邊時,w會出現在v的連結串列中,v也會出現在w的連結串列中。第二個建構函式從輸入流中讀取一幅圖,開頭是V,然後是E,再然後是一列整數對,大小在0到V-1之間。
相關文章
- 演算法(四):圖解狄克斯特拉演算法演算法圖解
- 基於遺傳演算法的地圖四色原理繪圖上色的Python程式碼演算法地圖繪圖Python
- 四象圖
- 【作業系統】磁碟的四種基本排程演算法(圖表說明)作業系統演算法
- GC的四種清理演算法GC演算法
- JVM的四種GC演算法JVMGC演算法
- 【演算法】分治四步走演算法
- PHP演算法之四大基礎演算法PHP演算法
- 演算法流程圖演算法流程圖
- 圖論演算法圖論演算法
- 圖論與圖學習(二):圖演算法圖論演算法
- 【JAVA演算法】圖論演算法 -- Dijkstra演算法Java演算法圖論
- 圖解四種 IO 模型圖解模型
- 演算法(八):圖解KNN演算法演算法圖解KNN
- 挑戰演算法題:四數之和演算法
- 【每日演算法】動態規劃四演算法動態規劃
- 圖解排序演算法圖解排序演算法
- 【圖論】Floyd演算法圖論演算法
- ugui 縮放圖片使圖片的四個角和四邊保持原樣UGUI
- 演算法(六):圖解貪婪演算法演算法圖解
- 圖論系列之「讀取圖演算法」圖論演算法
- 演算法(3)簡單四則運算演算法
- 【JVM】垃圾回收的四大演算法JVM演算法
- (新)app逆向四(常見加密演算法)APP加密演算法
- 【演算法】演算法圖解筆記_快速排序演算法圖解筆記排序
- 圖論-二分圖匹配匈牙利演算法圖論演算法
- 《演算法圖解》筆記演算法圖解筆記
- 演算法-點陣圖排序演算法排序
- 圖解JavaScript演算法排序圖解JavaScript演算法排序
- 圖解堆排序演算法圖解排序演算法
- Tableau實戰 貨架圖分析(四)
- 演算法(五):圖解貝爾曼-福特演算法演算法圖解
- 演算法小記·不用四則運算做加法演算法
- LRU演算法四種實現方式介紹演算法
- Java 虛擬機器(四)垃圾收集演算法Java虛擬機演算法
- 演算法(第四版)的準備演算法
- PHP 中四大經典排序演算法PHP排序演算法
- Ribbon提供的負載均衡演算法IRule(四)負載演算法