1. 程式人生 > >圖演算法 圖的表示(鄰接表和鄰接矩陣)和拓撲排序

圖演算法 圖的表示(鄰接表和鄰接矩陣)和拓撲排序

圖的表示

圖有兩種表示方法,分別是鄰接矩陣和鄰接表。這裡以有向圖為例說明。


鄰接矩陣

鄰接矩陣是一個二維陣列A。對於每條邊 (u,v),置A[u][v]等於true;否則,陣列元素為false。

如果邊有一個權,那麼可以置A[u][v]等於該權,而使用一個很大或者很小的權作為標記表示不存在的邊。

它的空間需求為Θ(|V|^2)。


鄰接表

大多數情況,圖都是比較稀疏的,那麼用鄰接表表示更為合適。

對每一個頂點,使用一個表存放所有鄰接的頂點。這樣的空間需求為Θ( |E| + |V| )。

鄰接表是圖的標準表示方法。可以為每個頂點資料結構增加一個鄰接表域才儲存這個表。


拓撲排序

拓撲排序是對有向無圈圖頂點的一種排序,是的如果存在一條從vi到vj的路徑,那麼在排序中vj就出現在vi後面。注意:只保證先後順序,不保證相鄰頂點挨著出現。

做法是:對每個頂點,除了保持鄰接表,還有入度(indegree,定義為邊(u,v)的條數),拓撲編號(topNum)。

使用一個佇列儲存入度為0的頂點。

1,對每個頂點計算它的入度,將所有入度為0的頂點放在一個初始為空的佇列;

2,當佇列不空時,刪除一個頂點v,並將於v鄰接的所有頂點的入度減1。

3,只要一個頂點的入度降為0,就將該頂點放入佇列中。

4,此時,拓撲排序就是頂點入隊的順序。

	//虛擬碼,可以很方便改寫為Java程式碼
	void topsort( ){
		//哪個佇列實現類的都可以
		Queue<Vertex> q = new Queue<Vertex>( );
		int counter = 0;
		
		for each Vertex v
			if( v.indegree == 0 )
				q.enqueue( v );
		
		while( !q.isEmpty( ) ){
			Vertex v = q.dequeue( );
			v.topNum = ++counter;
		
			for each Vertex w adjacent to v
				if( --w.indegree == 0 )
					q.enqueue( w );
		}
		
		if( counter != NUM_VERTICES )
			print("Circle exists!");
    }