一、圖的深度優(yōu)先概述圖,就是由一些小圓點(稱為頂點)和連接這些小圓點的直線(稱為邊)組成的。例如:
上圖是由五個頂點(編號為1、2、3、4、5)和五條邊(1-2、1-3、1-5、2-4、3-5)組成。
現(xiàn)在我們從1號頂點開始遍歷這個圖(遍歷指的是把每一個頂點都訪問一次)。使用深度優(yōu)先搜索來遍歷這個圖我們將得到以下結(jié)果:
使用深度優(yōu)先搜索來遍歷這個圖的具體過程是:
深度優(yōu)先遍歷的主要思想是:
在此我想用一句話來形容 “一路走到頭,不撞墻不回頭”。
二、實現(xiàn)顯而易見,深度優(yōu)先搜索遍歷是沿著圖的某一條分支遍歷直到末端,然后回溯,再沿著另一條進行同樣的遍歷,直到所有的頂點都被訪問過為止。 那么問題來了,該如何實現(xiàn)這一過程呢? 首先,我們來解決如何存儲一個圖的問題。最常用的方法是使用一個二維數(shù)組e來存儲,如下:
上圖二維數(shù)組中第 i 行第 j 列表示的就是頂點 i 到頂點 j 是否有邊。1 表示有邊,∞ 表示沒有邊,0 表示自己到自己(i=j)。這種存儲圖的方法稱為圖的鄰接矩陣存儲法。 同時我們發(fā)現(xiàn):這個二維數(shù)組是沿著主對角線對稱的,因此上面這個圖是無向圖。無向圖指的是圖的邊沒有方向,例如邊1-5表示,1號頂點可以到5號頂點,5號頂點也可以到達1號頂點。 void dfs(int cur)//cur是當(dāng)前所在的頂點編號 { printf('%d ',cur); sum++; //每訪問一個頂點sum就加1 if(sum==n) return; //所有的頂點都已經(jīng)訪問過則直接退出 for(i=1;i<=n;i++)>=n;i++)>//從1號頂點到n號頂點依次嘗試,看哪些頂點與當(dāng)前頂點cur有邊相連 { //判斷當(dāng)前頂點cur到頂點i是否有邊,并判斷頂點i是否已訪問過 if(e[cur][i]==1 && book[i]==0) { book[i]==1; //標記頂點i已經(jīng)訪問過 dfs(i); //從頂點i再出發(fā)繼續(xù)遍歷 } } return; }
在上面的代碼中變量cur存儲的是當(dāng)前正在遍歷的頂點,二維數(shù)組e存儲的就是圖的邊(鄰接矩陣),數(shù)組 book 用來記錄哪些頂點已經(jīng)訪問過,變量 sum 用來記錄已經(jīng)訪問過多少個頂點,變量 n 存儲的是圖的頂點的總個數(shù)。完整代碼如下: #include |
|
|