圖的DFS與BFS用好,能解決leetcode 25%的題目
DFS是一次走到底,(如果不用遞歸)所以要用stack保留之前信息(可理解成樹的先序遍歷),BFS每次只走一步,新添加的待遍歷點放入queue,等之後再遍歷。
其實我有一篇關於DFS和BFS很好的教材,不過是全英版的。鏈接戳這裏~
根據數據結構(C語言版)清華大學出版社:
DFS:
對於每個節點的相鄰節點都是用DFS,一條路走到黑。
Boolean visited[MAX]; //記錄某個節點是否被訪問過
Status(*VisitFunc)(int v); //函數變量
void DFSTraverse(Graph G, Status(*Visit)(int v)) {
VisitFunc = Visit; //使用全局變量VisitFunc 使DFS不必設函數指針參數
for(v = 0; v < G.vexnum; ++v) visited[v] = FALSE; //訪問標誌數組初始化
for(v = 0; v < G.vexnum; ++v)
if(!visited[v]) DFS(G, v); //對未訪問過的頂點調用DFS
}
void DFS(Graph G, int v) {
visited[v] = TRUE; VisitFunc(v); //訪問第 v 個節點
for(w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
if(!visited[w]) DFS(G, w); //對 v 的尚未訪問過的鄰接節點 w 遞歸調用 DFS
}
}
BFS:
對於每個節點,遍歷其所有鄰接節點,並放入隊列中(等之後再來遍歷鄰接節點的鄰接節點)
void BFSTraverse(Graph G, Status(*Visit)(int v)) {
//按照廣度優先非遞歸遍歷圖 G,使用輔助隊列 Q 和訪問標誌數組 visited
for(v = 0; v < G.vexnum; ++v) visited[v] = FALSE;
InitQueue(Q); //置空的輔助隊列
for(v = 0; v < G.vexnum; ++v)
if(!visited[v]) { //v 尚未訪問
EnQueue(Q, v); //v 入隊列
visited[v] = TRUE; Visit(v);
while(!QueueEmpty(Q)) { //隊列爲非空,則一直執行下去
DeQueue(Q, u); //隊頭元素出隊並置爲 u
for(w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w))
if(!visited[w]) { //w 爲 u 的尚未訪問的鄰接頂點
visited[w] = TRUE; Visit(w);
EnQueue(Q, w);
} // if
} // while
}// if
}// BFSTraverse