數據結構---圖的鄰接矩陣表示以及深度遍歷
鄰接矩陣表示
-
定義鄰接矩陣的數據結構表示
// 鄰接矩陣 typedef struct _graph { char vexs[MAX]; // 頂點集合 int vexnum; // 頂點數 int edgnum; // 邊數 int matrix[MAX][MAX]; // 鄰接矩陣 }Graph, *PGraph;
-
無向圖的邊的矩陣一定是一個對稱矩陣,因為無向圖只關心邊是否存在,而不關心方向,V0和V1有邊,那么V1和V0也有邊。
-
找到每個點(ch)在鄰接矩陣中的位置
static int get_position(Graph g, char ch) { int i; for(i=0; i<g.vexnum; i++) if(g.vexs[i]==ch) return i; return -1; }
-
自定義一個圖的連接方式 畫出和中例子相同的圖結構 用ABCDEFGH表示頂點
-
代碼實現
Graph* create_example_graph() { char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G','H' }; char edges[][2] = { { 'A', 'B' }, { 'A', 'C' }, { 'B', 'D' }, { 'B', 'E' }, { 'C', 'F' }, { 'C', 'G' }, { 'D', 'H' }, { 'E', 'H' }, { 'F', 'G' }}; int vlen = LENGTH(vexs); int elen = LENGTH(edges); int i, p1, p2; Graph* pG; // 輸入"頂點數"和"邊數" if ((pG = (Graph*)malloc(sizeof(Graph))) == NULL) return NULL; memset(pG, 0, sizeof(Graph)); // 初始化"頂點數"和"邊數" pG->vexnum = vlen; pG->edgnum = elen; // 初始化"頂點" for (i = 0; i < pG->vexnum; i++) { pG->vexs[i] = vexs[i]; } // 初始化"邊" for (i = 0; i < pG->edgnum; i++) { // 讀取邊的起始頂點和結束頂點 p1 = get_position(*pG, edges[i][0]); p2 = get_position(*pG, edges[i][1]); pG->matrix[p1][p2] = 1; pG->matrix[p2][p1] = 1; } return pG; }
-
打印鄰接矩陣
void print_graph(Graph G) { int i, j, k; printf("Martix Graph:\n"); for (i = 0; i < G.vexnum; i++) { for (j = 0; j < G.vexnum; j++) printf("%d ", G.matrix[i][j]); printf("\n"); } }
深度遍歷
- 圖的深度優先搜索(Depth First Search),和樹的先序遍歷比較類似。
- 假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
- 深度優先搜索是一個遞歸的過程
- 過程對比書上的例子
- 代碼實現
/*
* 深度優先搜索遍歷圖
*/
void DFSTraverse(Graph G)
{
int i;
int visited[MAX]; // 頂點訪問標記
// 初始化所有頂點都沒有被訪問
for (i = 0; i < G.vexnum; i++)
visited[i] = 0;
printf("DFS: ");
for (i = 0; i < G.vexnum; i++)
{
//printf("\n== LOOP(%d)\n", i);
if (!visited[i])
DFS(G, i, visited);
}
printf("\n");
}