深度優先搜尋 廣度優先搜尋(解決小哈)

2021-07-30 23:51:14 字數 3782 閱讀 3127

問題省略…

思路:讓小哼往右邊走,直到走不通的時候再回到這裡,再去嘗試另乙個方向。規定乙個順序,按順時針方向來嘗試(即按照右、下、左、上的順序去嘗試)。

檢查小哼是否已經到達小哈的位置,如果沒有到達則找出下一步可以走的地方。為了解決這個問題,此處dfs()函式只需要維護3個引數,分別是x座標、y座標、以及當前已經走過的步數step。dfs函式定義如下:

void dfs(int x,int y,int step)
判斷是否已經到達小哈位置,只需要判斷當前的座標和小哈的座標是否相等即可,如果相等則表明已經到達小哈的位置,如下:

void dfs(int x,int y,int step) 		

return;

}

int next[4][2]=,//向右 

,//向下

,//向左

};//向上

};

通過這個方向陣列,使用迴圈就很容易獲得下一步的座標。此處將下一步的橫座標用tx儲存,左邊用ty儲存。

for(int k=0;k<=3;k++)
接下來要對tx、ty進行一些判斷。包括是否越界、是否為障礙物,以及這個點是否已經在路徑中(避免重複訪問乙個點)。需要用book[tx][ty]來記錄格仔(tx,ty)是否已經在路徑中。

如果這個點符合所有要求,就對這個點進行下一步的擴充套件,即dfs(tx,ty,step+1).注意,此處的step+1,因為一旦從這個點開始繼續往下嘗試,意味著你的步數已經增加1.

for(int k=0;k<=3;k++) 

}

完整**:

#include#includeusing namespace std;

int a[51][51],book[51][51];

int n,m,p,q,minn=99999999;

void dfs(int x,int y,int step) ,//向右

,//向下

,//向左

};//向上

//判斷是否到達小哈位置

if(x==p && y==q)

int tx,ty;

for(int k=0;k<=3;k++)

} return ; }

int main() ;

struct note que[2501];

int head,tail;

int a[51][51]=;//用來儲存地圖

int book[51][51]=;//作用是記錄哪些點已經佇列中,防止乙個點被重複拓展,全部初始化為0

//最開始需要進行初始化,即將佇列設定為空

head=1;

tail=1;

que[tail].x=1;

que[tail].y=1;

que[tail].s=0;

tail++;

book[1][1]=1;

}

然後從(1,1)開始,先嘗試往右走到達(1,2)。

tx=que[head].x;

ty=que[head].y+1;

需要判斷(1,2)是否越界。

//判斷是否越界 

if(tx<1 || tx>n || ty<1 || ty>m)

continue;

再判斷(1,2)是否為障礙物或者已經在路徑中

//判斷是否為障礙物 或者已經在路徑中 

if(a[tx][ty]==0 && book[tx][ty]==0)

若滿足上述兩個條件,則將(1,2)入隊,並標記該點已經走過。

book[tx][ty]=1;	//把這個點標記為走過,注意寬搜每個點只入列一次,所以和深搜不同,不需要將book陣列還原 

//插入新的點到佇列中

que[tail].x=tx;

que[tail].y=ty;

que[tail].s=que[head].s+1;

tail++;

接下來還有繼續嘗試其他方向走。此處規定乙個順序,即按照順時針方向來嘗試(也就是以右下左上順序嘗試)。發現從(1,1)還是可以到達(2,1),因此 也需要將(2,1)也加入佇列,實現**與剛才一樣。

對(1,1)拓展完畢後,(1,1)對我們已經沒有用,此時將(1,1)出隊。出隊操作,即:

head++;
接下來需要在新拓展出的(1,2)和(2,1)這兩點的基礎上繼續向下探索。到目前為止已經拓展出從起點出發一步以內可以到達的所有點。因為還沒有到達小哈的位置,所以繼續。直至走到小哈位置,演算法結束、

完整**:

#include#includeusing namespace std;

struct note ;

int main() ,book[51][51]=;

//定義乙個用於表示走的方向的陣列

int next[4][2]=,//向右

,//向下

,//向左

};//向上

int k,n,m,tx,ty,flag;

cin>>n>>m;

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

cin>>a[i][j];

int startx,starty,p,q;

cin>>startx>>starty>>p>>q;

//佇列初始化

int head,tail;

head=1;

tail=1;

//往佇列插入迷宮入口座標

que[tail].x=startx;

que[tail].y=starty;

que[tail].f=0;

que[tail].s=0;

tail++;

book[startx][starty]=1;

flag=0;//用來標記是否到達目標點,0表示暫時沒有到達,1表示到達

while(headn || ty<1 || ty>m)

continue;

//判斷是否為障礙物 或者已經在路徑中

if(a[tx][ty]==0 && book[tx][ty]==0)

if(tx==p &&ty==q)

} if(flag==1)

break;

head++;//此地方不能忘記,當乙個點拓展結束,head++才能對後面的點再進行拓展

} //列印佇列中末尾最後乙個點(目標點)的步數

//注意tail是指向佇列隊尾(即最後一位)的下乙個位置,所以這需要-1

printf("%d",que[tail-1].s);

getchar();getchar();

return 0;

}

節選自《啊哈,演算法》這一本書,作者啊哈

廣度優先搜尋 深度優先搜尋

前言 這幾天複習圖論演算法,覺得bfs和dfs挺重要的,而且應用比較多,故記錄一下。廣度優先搜尋 有乙個有向圖如圖a 圖a廣度優先搜尋的策略是 從起始點開始遍歷其鄰接的節點,由此向外不斷擴散。1.假設我們以頂點0為原點進行搜尋,首先確定鄰接0的頂點集合s0 2.然後確定頂點1的集合s1 頂點2沒有鄰...

廣度優先搜尋,深度優先搜尋

深度優先搜尋 depth first search 簡稱dfs。最直觀的例子就是 走迷宮 廣度優先搜尋 每個頂點都要進出一遍佇列,每個邊也都會被訪問一次,所以 時間複雜度o v e 主要消耗記憶體的是visited prev陣列 queue佇列,所以 空間複雜度o v 深度優先搜尋 每條邊最多會被訪...

深度優先搜尋 廣度優先搜尋

深度優先搜尋 廣度優先搜尋 通過鄰接矩陣對圖進行深搜和廣搜 package com.neusoft.data.structure 深度優先搜尋 廣度優先搜尋 通過鄰接矩陣對圖進行深搜和廣搜 public class dfsbfs 初始化 邊 mmatrix new int vlen vlen for...