無向圖的深度優先遍歷
阿新 • • 發佈:2019-02-06
描述
簡單介紹一下圖,圖就是由一些小圓點(稱為頂點)和連線這些小圓點的直線(稱為邊)組成的。例如下圖的由五個頂點(編號1、2、3、4、5)和五條邊(1-2、1-3、1-5、2-4、3-5)組成
現在從1號頂點開始遍歷這個圖,遍歷是指把圖的每一個頂點都訪問一次。使用深度有限搜尋來遍歷這個圖將會得到如下結果。
這五個頂點的訪問順序如下圖
使用深度優先搜尋來遍歷這個圖的過程具體是:首先以一個未被訪問過的頂點為起始頂點,沿當前頂點的邊走到未訪問過的頂點:當沒有未訪問的頂點時,則回到上一個頂點,繼續試探訪問別的頂點,直到所有的頂點都被訪問過。顯然,深度優先遍歷是沿著圖的某一條分支遍歷直到末端,然後回溯,在沿著另一條進行同樣的遍歷,直到所有的頂點都被訪問過為止。
思路
首先用一個二維陣列e來儲存無向圖,如下
上圖中第 i 行 j 列表示頂點 i 到頂點 j 是否有邊。1 表示有邊,正無窮表示沒有邊,0 表示自己到自己。
這種儲存方法為鄰接矩陣的儲存方法
因為是無向圖,所以上面的二維陣列是沿對角線堆成的
程式碼塊
深度優先演算法程式碼
void dfs(int cur) { int i = 0; printf("%d ", cur);//輸出當前點 sum++; if (sum == n)//如果訪問完所有的點則返回 { return; } for (i = 1; i <= n; i++) { if (e[cur][i] == 1 && book[i] == 0)//如果cur結點到i結點可以連線則標記為已經訪問 { //且遞迴訪問i結點 book[i] = 1; dfs(i); } } return; }
cur 儲存的是當前正在遍歷的頂點,二維陣列 e 儲存的就是鄰接矩陣,陣列 book 用來記錄哪些頂點是遍歷過的,sum 用來記錄遍歷了多少個頂點,n 為頂點的總個數
原始碼
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> /* * 使用深度優先搜尋來遍歷一個無向圖 * 郭文峰 * 2018/10/17 */ int n, m, sum; int book[101], e[101][101]; void dfs(int cur) { int i = 0; printf("%d ", cur);//輸出當前點 sum++; if (sum == n)//如果訪問完所有的點則返回 { return; } for (i = 1; i <= n; i++) { if (e[cur][i] == 1 && book[i] == 0)//如果cur結點到i結點可以連線則標記為已經訪問 { //且遞迴訪問i結點 book[i] = 1; dfs(i); } } return; } int main(void) { int i = 0; int j = 0; int a = 0; int b = 0; //用一個二維陣列e[][]來儲存一個無向圖 //輸入這個無向圖共有幾個數字 scanf("%d%d", &n, &m); for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { if (i == j) { e[i][j] = 0; //二維陣列中用0代表自己到自己 } else { e[i][j] = 999999999; //二維陣列中用999999999來表示正無窮 } } } for (i = 1; i <= n; i++) { scanf("%d%d", &a, &b); e[a][b] = 1; e[b][a] = 1; //因為是無向圖,所以雙向都等於1 } book[1] = 1;//1號標記已經訪問 dfs(1);//從1號頂點開始遍歷 system("pause"); return 0; }