廣度優先搜索 BFS算法


廣度優先搜索算法(Breadth-First-Search,BFS),又稱做寬度優先搜索。BFS算法是從根節點開始,沿着樹的寬度遍歷樹的節點。若是全部節點均被訪問,則算法停止。html

算法思想

一、首先將根節點放入隊列中。node

二、從隊列中取出第一個節點,並檢驗它是否爲目標。算法

  • 若是找到目標,則結束搜索並回傳結果。
  • 不然將它全部還沒有檢驗過的直接子節點加入隊列中。

三、若隊列爲空,表示整張圖都檢查過了——亦即圖中沒有欲搜索的目標。結束搜索並回傳「找不到目標」。編程

四、重複步驟2。spa

搜索過程演示

說明

  • 灰色的是加入隊列中的活動節點,黑色是從活動節點隊列中選取的擴展節點。.net

  • 每次將一個活動節點標記爲擴展節點後,進行判斷,並將該點從活動節點隊列中移除,再將該節點全部未檢測的子節點加入活動節點隊列中去。3d

  • 接下來再從隊列中選取新的活動節點做爲擴展節點,如此循環下去,直至隊列爲空爲止,說明已經遍歷過全部的節點。rest

複雜度

  • 由於全部節點都必須被存儲,所以BFS的空間複雜度爲 O(|V|+|E|),其中 |V| 是節點的數目,而 |E| 是圖中邊的數目。code

  • 最差情形下,BFS必須查找全部到可能節點的全部路徑,所以其時間複雜度爲 O(|V|+|E|)。htm

C++實現

//Given a binary tree, find its minimum depth.
//The minimum depth is the number of nodes along 
//the shortest path from the root node down to 
//the nearest leaf node.


// 遞歸方法
class Solution 
{

public:
    int run(TreeNode *root) 
         {
        if (!root)
        {
            return 0;
        }

        // 若左子樹爲空,返回右子樹深度 + 1
        if (root->left == nullptr)
        {
            return (run(root->right) + 1);
        }
        // 若右子樹爲空,返回左子樹深度 + 1
        if (root->right == nullptr)
        {
            return (run(root->left) + 1);
        }

        // 左右子樹都不爲空,返回較小值
        int leftDepth = run(root->left);
        int rightDepth = run(root->right);
        return ((leftDepth < rightDepth) ? (leftDepth + 1) : (rightDepth + 1));

    }
};



// BFS方法

#include <vector>
using namespace std;
class Solution
{
public:
    int run(TreeNode *root)
         {
        if (!root)
        {
            return 0;
        }

        vector <TreeNode *> que;
        TreeNode *now = root;  // 當前訪問的節點
        TreeNode *last = root;  // 每層最後的一個節點
        que.push_back(root);
        int depth = 1;  // 初始深度

        while (que.size())
        {
            // 取出隊列中的第一個節點做爲當前節點
            now = que.front();
            que.erase(que.begin());

            // 若是當前節點沒有子節點了,直接終止循環,說明是葉子節點,返回最小深度
            if ((now->left == nullptr) && (now->right == nullptr))
            {
                break;
            }

            // 將子節點加入隊列中
            if (now->left != nullptr)
            {
                que.push_back(now->left);
            }
            if (now->right != nullptr)
            {
                que.push_back(now->right);
            }

            // 當訪問到每層的最後一個節點時,深度+1
            if (now == last)
            {
                depth++;
                last = que.back();  // 將下一層最後一個節點賦給last
            }

        }
        
        return depth;

    }

};

BFS在迷宮問題的應用


References

相關文章
相關標籤/搜索