图的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