1.介紹圖的相關概念
圖是由頂點的有窮非空集和一個描述頂點之間關系-邊(或者弧)的集合組成。通常,圖中的數據元素被稱為頂點,頂點間的關系用邊表示,圖通常用字母G表示,圖的頂點通常用字母V表示,所以圖可以定義為:
G=(V,E)
其中,V(G)是圖中頂點的有窮非空集合,E(G)是V(G)中頂點的邊的有窮集合
1.1 無向圖:圖中任意兩個頂點構成的邊是沒有方向的
1.2 有向圖:圖中任意兩個頂點構成的邊是有方向的,通常有向圖的邊也稱之為弧
1.3 完全圖:圖中任意一個頂點與其他節點之間都有邊
1.4 稠密圖、稀疏圖:一個圖接近完全圖稱為稠密圖,邊數很少的圖稱為稀疏圖
1.6 頂點的度:依附於某頂點的邊數稱為該頂點的度,在有向圖中,以頂點為終點的弧的數目為該頂點的入度,以該點為始點的弧數為該頂點的出度
1.7 權:圖中與邊或弧有關的數據信息
1.8 網:邊上帶權的圖稱為網或帶權圖
1.9 路徑、路徑長度:無向圖中,從任意一點到另一點所經過的頂點序列稱為路徑,路徑上的邊數稱為路徑長度
2.0 簡單路徑、簡單回路、回路:一條路徑中,若路徑序列中所有頂點除起始點和中止點之外,彼此都不同,則該路徑為簡單路徑。簡單路徑中的起始點與中止點相同,該路徑為簡單回路。如果路徑序列中起始點與中止點相同,則該路徑為回路或者環。
2.1 連通、連通圖:無向圖中,某兩頂點之間有路徑,則稱這兩個頂點是連通的。如果圖中任意兩頂點都是連通的,則該無向圖為連通圖,否則為非連通圖。
2.2 極大連通子圖、連通分量:如果在向無向連通圖中加入原圖的任何一個頂點,子圖就不連通,則為極大連通分量。無向連通圖中的極大連通子圖稱為該無向圖的連通分量。/在有向圖中若任意兩頂點存在兩條弧(一個入度一個出度),則稱為強連通圖,強連通分量同理。
圖G的三個連通分量:
2.圖的存儲
鄰接矩陣是表示頂點間相鄰關系的矩陣,無向圖中,如果兩頂點有邊,則G[i][j] = G[j][i] = 1,反之為0,有向圖中G[i][j] = 1,但是G[j][i] 未必等於1
也可以表示帶權圖,即將1換位權值即可
程序:
1 //建立圖的鄰接矩陣算法程序 /有向圖,無權值,兩頂點之間有邊就用1表示,無邊用0表示 2 #include<stdio.h> 3 #include<string.h> 4 #define MAX_VEX 100 5 6 int creatcost(int cost[][MAX_VEX]) //*cost數組表示所有帶權圖的鄰接矩陣 7 { 8 int vexnum,arcnum,i,j,k,v1,v2; //輸入圖的頂點數和邊數(或弧數) 9 10 printf("\n請輸入頂點數,邊數:\n"); 11 scanf("%d %d",&vexnum,&arcnum); 12 for(i = 1;i <= vexnum;i++) //初始化帶權圖的鄰接矩陣 13 for(j = 1;j <= vexnum;j++) 14 cost[i][j] = 0; //0表示無窮大 15 //memset(cost,0,vexnum*vexnum); //也可以使用memset()函數進行初始化,將整個矩陣置0,需要有文件string.h 16 for(k = 0;k < arcnum;k++) 17 { 18 printf("v1,v2= "); 19 scanf("%d %d",&v1,&v2); 20 cost[v1][v2] = 1; 21 //cost[v2][v1] = 1; //若建立無向圖的鄰接矩陣就應該加上這句話 22 } 23 24 return vexnum; 25 } 26 27 int main() 28 { 29 int i,j,vexnum; 30 int cost[MAX_VEX][MAX_VEX]; 31 vexnum = creatcost(cost); 32 printf("所建圖的鄰接矩陣為:\n"); 33 for(i = 1;i <= vexnum;i++) 34 { 35 for(j = 1;j <= vexnum;j++) 36 printf("%3d",cost[i][j]); 37 printf("\n"); 38 } 39 40 return 0; 41 }
鄰接矩陣存儲其實有一些問題,對於邊數相對頂點較少的圖,這種存儲結構對存儲空間存在極大的浪費