深度優先搜索算法DFS
廣度優先搜索算法BFS
在豬呢個算法知識點中佔比非常大,應用最多的地方是對圖進行遍歷(樹以爲是圖的一種)
深度優先搜索算法DFS
DFS解決的 是連通性的問題,及給定兩個起始點(或某種起始狀態)和一個終點(某種最終狀態),判斷是否有一條路徑能從起點連接到終點。
很多情況下,聯通的路徑很多條,只需要找出一條即可,DFS只關心路徑存在與否,不在乎其長短。
算法的思想:從起點出發,選擇一個可選方向不斷向前,直到無法繼續爲止。
然後嘗試另外一種方向,直到最後走到終點。
boolean dfs(int maze[][],int x,int y)
{
if(x == B[0] && y == B[1])//判斷是否抵達了目的地B,是則立即返回。
{
return true;
}
maze[x][y] == -1; //標記當前已經被訪問過的點(一般標記是否被訪問過,直接修改訪問過的數據,利用一個額外的數據結構來記錄)
for(int d =0;d<4;d++) 在規定的4個方向上進行嘗試
{
int i =x+dx[d];
int j =y+dy[d];
if(isSafe(maze,i,j)&& dfs(maze,i,j)) 對於每個要嘗試的方向,檢查是否越界。以及新的點是否已經被訪問過了。
{
return true; 如果有一條路徑被找到了,則返回true
}
}
return false; 嘗試了所有可能還沒找到B,則返回false
}
DFS遞歸實現
利用遞歸去實現DFS可以讓代碼看上去很簡潔
遞歸的時候需要講話當前程序中的變量及及狀態壓入到系統的棧裏面
壓入和彈出都需要較多的時間,如果需要壓入很深的棧,會造成運行效率低下。
DFS非遞歸實現:
棧的數據結構也支持壓入和彈出操作。
bool dfs(int maze[][],int x,int y)
{
stack<int[]>stack =new stack<>();//創建一個stack,用來將要訪問的點壓入及彈出
maze[x][y] = -1; //將起始點壓入棧,並標記爲被訪問過。
while(!stack.empty())//只要stack不爲空,就不斷地循環,處理每一個點
{
int pos[] =stack.pop();
x =pos[0]; //從堆棧取出當前要處理的點
y =pos[1];
if(x==B[0]&&y ==B[1]) //判斷是否抵達了目的地B,否則返回ture
{
return true;
}
}
for(int d =0;d<4;d++) //如果不是就從4個方向上去嘗試
{
int i=x+dx[d];
int j =y+dy[d];
if(issafe(maze,i,j))
{
stack.push(new int[]{i,j}); //將各個方向上的點壓入堆棧,並把標記爲訪問過
maze[i][j] =-1;
}
}
return false;//嘗試了所有可能還沒有找到B,返回false
}