1. 程式人生 > 實用技巧 >dfs和bfs

dfs和bfs

1.dfs(深度優先搜尋)是兩個搜尋中先理解並使用的,其實就是暴力把所有的路徑都搜尋出來,它運用了回溯,儲存這次的位置,深入搜尋,都搜尋完了便回溯回來,搜下一個位置,直到把所有最深位置都搜一遍,要注意的一點是,搜尋的時候有記錄走過的位置,標記完後可能要改回來;

回溯法是一種搜尋法,按條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法;

例如這張圖,從1開始到2,之後到5,5不能再走了,退回2,到6,退回2退回1,到3,一直進行;

理解這種方法比較簡單,難的是要怎麼用

void dfs(int deep)
{
	int x=deep/n,y=deep%n;
	if(符合某種要求||已經不能在搜了)
	{
		做一些操作;
		return ;
	}
	if(符合某種條件且有地方可以繼續搜尋的)//這裡可能會有多種條件,可能要迴圈什麼的
	{
		a[x][y]='x';//可能要改變條件,這個是瞎寫的
	        dfs(deep+1,sum+1);//搜尋下一層
		a[x][y]='.';//可能要改回條件,有些可能不用改比如搜地圖上有多少塊連續的東西
	}
}

2.bfs(寬度/廣度優先搜尋),這個一直理解了思想,不會用,後面才會的,思想,從某點開始,走四面可以走的路,然後在從這些路,在找可以走的路,直到最先找到符合條件的,這個運用需要用到佇列(queue),需要稍微掌握這個才能用bfs。


一張圖,bfs就是和它類似,很好的幫助理解,雷從上往下,同時向四面八方的延長(當然不是很嚴謹的),然後找到那個最近的建築物,然後劈了它;

還是這張圖,從1開始搜,有2,3,4幾個點,存起來,從2開始有5,6,存起來,搜3,有7,8,存起來,搜4,沒有了;現在開始搜剛剛存的點,從5開始,沒有,然後搜6.。。一直進行,直到找到;

int visit[N][N]//用來記錄走過的位置
int dir[4][2]={0,-1,0,1,-1,0,1,0};
struct node
{
	int x,y,bits;//一般是點,還有步數,也可以存其他的
};
queue<node>v;
void bfs1(node p)
{
	node t,tt;
	v.push(p);
	while(!v.empty())
	{
		t=v.front();//取出最前面的
		v.pop();//刪除
		if(找到符合條件的)
		{
			做記錄;
			while(!v.empty()) v.pop();//如果後面還需要用,隨手清空佇列
			return;
		}
		visit[t.x][t.y]=1;//走過的進行標記,以免重複
		rep(i,0,4)//做多次查詢
		{
			tt=t;
			tt.x+=dir[i][0];tt.y+=dir[i][1];//這裡的例子是向上下左右查詢的
			if(如果這個位置符合條件)
			{
				tt.bits++;//步數加一
				v.push(tt); //把它推入佇列,在後面的時候就可以用了
			}
		}
	}
}

3.dfs和bfs的區別

其實有時候兩個都可以用,不過需要其他的東西來記錄什麼的,各自有各自的優勢

bfs是用來搜尋最短徑路的解法是比較合適的