1. 程式人生 > 實用技巧 >簡述BFS與DFS

簡述BFS與DFS

簡述BFS與DFS

最近學習了資料結構課程以及應對藍橋杯備考,所以花費了一點時間將比較重要的兩個搜尋BFS(寬度優先搜尋)和DFS(深度優先搜尋)大致思路以及程式碼整理出來,如有錯誤,還請各位大佬批評改正。

PS:用了幾天時間試探著做了一個簡單的靜態網頁,包括購買伺服器,建站,以及程式碼編寫,過幾天我會給出具體流程。大牛勿噴網站地址*/

##所謂搜尋,實質就是遍歷,只是在處理不同問題時加一些限制條件而已,比如走迷宮,則需要從出發點開始,向終點不斷試探,當到達終點,則break提前結束遍歷。
在這裡推薦浙江大學PAT中計算圖的連通集這道題,非常基礎,下面我會給出題解。連結:浙大PAT連通集

DFS(深度優先搜尋)

所謂深度,就類似樹的先序遍歷,形象的說就是一條路走到黑,如果走到頭了,則返回上一個節點,所以我們很自然會想到用遞迴實現,另外加一個標記陣列,確保節點只訪問一次。(這裡建議鄰接矩陣跟標記陣列全部使用全域性變數,不然的話函式傳參會很麻煩)

void dfs(int now)
{
	cout << now << " ";
	book[now] = 1;
	for (int t = 0; t < point; t++)
	{
		if (shang[now][t] == 1 && book[t] == 0)
			dfs(t);
	}
	return;
}

上述為DFS函式,每次遞迴後都會找到與之相鄰的節點,並再次遞迴,直到所有節點全部遍歷一次。

BFS(廣度優先搜尋)

所謂廣度優先就類似樹裡面的層序遍歷,每次訪問的是同層的節點,同層訪問後再繼續向下訪問,這裡我們用佇列來實現,利用佇列的先進先出性質,每次遞增訪問,這樣通過廣度優先,我們可以得到迷宮的最短路徑。

void bfs(int now)
{
	struct quee q;
	book[now] = 1;
	q.number[q.top] = now;
	q.top++;
	//cout << endl<<endl<<endl<< q.tail << " " << q.top;
	while (q.tail != q.top) {
		now = q.number[q.tail];
		q.tail++;
		cout << now << " ";
		for (int t2 = 0; t2 < point; t2++)
		{
			if (shang[now][t2] == 1 && book[t2] == 0)
			{
				q.number[q.top] = t2;
				q.top++;
				book[t2] = 1;
			}
		}
	}

}

浙大PAT列出所有連通集:
06-圖1 列出連通集 (25分)
給定一個有N個頂點和E條邊的無向圖,請用DFS和BFS分別列出其所有的連通集。假設頂點從0到N−1編號。進行搜尋時,假設我們總是從編號最小的頂點出發,按編號遞增的順序訪問鄰接點。

輸入格式:
輸入第1行給出2個整數N(0<N≤10)和E,分別是圖的頂點數和邊數。隨後E行,每行給出一條邊的兩個端點。每行中的數字之間用1空格分隔。

輸出格式:
按照{v1,v2,V3…}的格式,每行輸出一個連通集。先輸出DFS的結果,再輸出BFS的結果。
輸入樣例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5
輸出樣例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }
看到題目就會覺得很基礎,只是單純的考一下BFS和DFS,用一個鄰接矩陣將圖的關係存入,然後分別呼叫兩個函式,再按照樣例格式輸出即可
AC程式碼

#include<iostream>
using namespace std;
int point, leg;
int shang[1005][1005] = { 0 };
int book[1005] = { 0 };
struct quee
{
	int top=0, tail=0;
	int number[1005];
};
void dfs(int now)
{
	cout << now << " ";
	book[now] = 1;
	for (int t = 0; t < point; t++)
	{
		if (shang[now][t] == 1 && book[t] == 0)
			dfs(t);
	}
	return;
}
void bfs(int now)
{
	struct quee q;
	book[now] = 1;
	q.number[q.top] = now;
	q.top++;
	//cout << endl<<endl<<endl<< q.tail << " " << q.top;
	while (q.tail != q.top) {
		now = q.number[q.tail];
		q.tail++;
		cout << now << " ";
		for (int t2 = 0; t2 < point; t2++)
		{
			if (shang[now][t2] == 1 && book[t2] == 0)
			{
				q.number[q.top] = t2;
				q.top++;
				book[t2] = 1;

			}
		}
	}

}
int main()
{
	int L1, L2;
	cin >> point >> leg;
	for (int t = 0; t < leg; t++) {
		cin >> L1 >> L2;
		shang[L1][L2] = 1;
		shang[L2][L1] = 1;
	}
	for (int t3 = 0; t3 < point; t3++)
	{
		if (book[t3] == 0) {
			cout << "{ ";
			dfs(t3);
			cout << "}";
			cout << endl;
		}
		
	}
	for (int t3 = 0; t3 < point; t3++)
		book[t3] = 0;
	for (int t3 = 0; t3 < point; t3++)
	{
		if (book[t3] == 0) {
			cout << "{ ";
			bfs(t3);
			cout << "}";
			cout << endl;
		}

	}
}