图的DFS与BFS

图的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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章