【 聲明:著作權,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】
圖是資料結構裡面的重要一章。通過圖,我們可以判斷兩個點之間是不是具有連通性;通過圖,我們還可以計算兩個點之間的最小距離是多少;通過圖,我們還可以根據不同的要求,尋找不同的合適路徑。當然,有的時候為了計算的需要,我們還需要抽象出最小產生樹,這樣在遍曆計算的時候就不需要持續判斷是不是遇到了迴圈節點。當然,這所有的一切都是從圖的表示開始的。
1)矩陣表示
矩陣表示可以說是最簡單的表示方法,如果說一個圖中有5個點,那麼我們就可以構建一個5*5的矩陣。如果點和點之間存在串連,那麼填上1;反之如果不存在串連,那麼可以用0表示,當然對角線上面的點是沒有意義的。如所示:
static int graph[5][5] = {{0, 1, 0, 1, 1},{1, 0, 1, 0, 1},{0, 1, 0, 1, 0},{1, 0, 1, 0, 1},{1, 1, 0, 1, 0}};
如果點和點之間還是存在方向的,那麼它們關於(x,x)對稱軸就是不對稱的,所以結果也可能是這樣的:
static int graph[5][5] = {{0, 0, 0, 0, 0},{1, 0, 0, 0, 0},{0, 1, 0, 0, 0},{1, 0, 1, 0, 0},{1, 1, 0, 1, 0}};
當然,如果點和點之間的關係存在某種權重,比如說距離,那我們可以用它來代替原來的資料1:
static int graph[5][5] = {{0, 0, 0, 0, 0},{3, 0, 0, 0, 0},{0, 6, 0, 0, 0},{8, 0, 4, 0, 0},{9, 2, 0, 7, 0}};
矩陣表示下的圖結構非常直觀。但是,矩陣有一個特點,就是比較浪費空間。因為我們這裡舉例的頂點比較少,只有5個,但是請大家試想一下,如果一張圖上有10000個節點,那麼10000*10000該是多大的一個空間啊。重要的是,這10000*10000上面大多數點都是0,所以浪費的空間是相當可觀的。
2)數組結構
為了改變矩陣浪費空間的特點,我們可以建立一個只有頂點和邊組成的資料空間。比如說,我們定義一個這樣的結構:
typedef struct _LINE{int start;int end;int weight;int isDirection;}LINE;
上面定義的資料結構非常簡潔。第1個為起始頂點,第2個為終點,第3個為權重,第4個判斷當前邊是否有向。圖中要是有多少邊,我們就要定義多少個這樣的資料。如果把這些邊的資料都放在一起構成一個數組,那麼我們就可以用這個數組來表示圖的全部資訊了。
但是,我們還是覺得有遺憾的地方。這個資料結構過分強調了邊的意義和重要性,忽略了頂點本身的含義。因為,我們在強調邊的時候,應該添加進頂點的相關特性。離開頂點的支援,單純的邊資訊是沒有什麼含義的。
3)基於頂點鏈表的圖表示
首先,我們定義頂點的基本結構:
typedef struct _LINE{int end;int weight;struct _LINE* next;}LINE;typedef struct _VECTEX{int start;int number;LINE* neighbor;}VECTEX;
我們用VECTEX記錄頂點的相關資訊,LINE表示節點的相關資訊。如果LINE是在VECTEX中的變數,那麼neighbor表示當前所有節點的起始點都是start點。如果它是PATH中的變數呢,那麼next的起始點就是LINE連結的前面一個點,不知道我講清楚了沒有?下面就是點與點之間PATH的定義。
typedef struct _PATH{int start;int end;int lenth;LINE* next;}PATH;
其中start為起始點,end為終結點,next為start連結的下一個點,lenth為路徑的總長度,當然也可以修改成其他的權重形式。
注意事項:
1)數組和鏈表是圖結構的基礎,朋友們應該好好掌握
2)每一種資料結構都有自己的應用場合,關鍵是理解其中的思想和方法
3)圖的表示是圖運算的基礎,掌握它們是我們進一步學習的基本條件