【程式碼隨想錄】廣度優先搜尋

SaTsuki26681534發表於2024-03-20

思路分析

image
先前已經做過一道深度優先搜尋了,可以看出,DFS比較適合求兩點之間的所有路徑這樣的問題,因為其路徑都是逐條求出的,而BFS則可能一下子求出多條路徑,適合用來求最短路徑。
關於BFS的過程前面已經學習過很多次了,遍歷到一個節點時要先儲存其所有鄰接節點再繼續向下遍歷,一般是使用一個佇列來完成。
image

程式碼模版

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 表示四個方向
// grid 是地圖,也就是一個二維陣列
// visited標記訪問過的節點,不要重複訪問
// x,y 表示開始搜尋節點的下標
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
    queue<pair<int, int>> que; // 定義佇列
    que.push({x, y}); // 起始節點加入佇列
    visited[x][y] = true; // 只要加入佇列,立刻標記為訪問過的節點
    while(!que.empty()) { // 開始遍歷佇列裡的元素
        pair<int ,int> cur = que.front(); que.pop(); // 從佇列取元素
        int curx = cur.first;
        int cury = cur.second; // 當前節點座標
        for (int i = 0; i < 4; i++) { // 開始想當前節點的四個方向左右上下去遍歷
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1]; // 獲取周邊四個方向的座標
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 座標越界了,直接跳過
            if (!visited[nextx][nexty]) { // 如果節點沒被訪問過
                que.push({nextx, nexty});  // 佇列新增該節點為下一輪要遍歷的節點
                visited[nextx][nexty] = true; // 只要加入佇列立刻標記,避免重複訪問
            }
        }
    }

}

補充:pair,在這裡用來表示點的座標

image
https://blog.csdn.net/sevenjoin/article/details/81937695

相關文章