BFS算法模板(python實現)


BFS算法整理(python實現)

廣度優先算法(Breadth-First-Search),簡稱BFS,是一種圖形搜索演算算法。

1. 算法的應用場景

2. 算法的模板

2.1 針對樹的BFS模板

  • 無需分層遍歷
from collections import deque

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None


def level_order_tree(root, result):
    if not root:
        return
    # 這里借助python的雙向隊列實現隊列
    # 避免使用list.pop(0)出站的時間復雜度為O(n)
    queue = deque([root])

    while queue:
        node = queue.popleft()
        # do somethings
        result.append(node.val)
        if node.left:
            queue.append(node.left)
        if node.right:
            queue.append(node.right)
    return result


if __name__ == "__main__":
    tree = TreeNode(4)
    tree.left = TreeNode(9)
    tree.right = TreeNode(0)
    tree.left.left = TreeNode(5)
    tree.left.right = TreeNode(1)

    print(level_order_tree(tree, []))
    # [4, 9, 0, 5, 1]
  • 需要分層遍歷
def level_order_tree(root):
    if not root:
        return
    q = [root]
    while q:
        new_q = []
        for node in q:
            # do somethins with this layer nodes...
            # 判斷左右子樹
            if node.left:
                new_q.append(node.left)
            if node.right:
                new_q.append(node.right)
        # 記得將舊的隊列替換成新的隊列
        q = new_q
    # 最后return想要返回的東西
    return xxx

2.2 針對圖的BFS

  • 無需分層遍歷的圖
from collections import deque
def bsf_graph(root):
    if not root:
        return
    # queue和seen為一對好基友,同時出現
    queue = deque([root])
    # seen避免圖遍歷過程中重復訪問的情況,導致無法跳出循環
    seen = set([root])
    while queue:
        head = queue.popleft()
        # do somethings with the head node
        # 將head的鄰居都添加進來
        for neighbor in head.neighbors:
            if neighbor not in seen:
                queue.append(neighbor)
                seen.add(neighbor)
    return xxx
  • 需要分層遍歷的圖
def bsf_graph(root):
    if not root:
        return 
    queue = [root]
    seen = set([root])
    while queue:
        new_queue = []
        for node in queue:
            # do somethins with the node
            for neighbor in node.neighbors:
                if neighbor not in seen:
                    new_queue.append(neighbor)
                    seen.add(neighbor)
    return xxx
            

2.3 拓撲排序

在圖論中,由一個有向無環圖的頂點組成的序列,當且僅當滿足下列條件時,稱為該圖的一個拓撲排序(英語:Topological sorting)。

每個頂點出現且只出現一次;
若A在序列中排在B的前面,則在圖中不存在從B到A的路徑。
實際應用

  • 檢測編譯時的循環依賴
  • 制定有依賴關系的任務的執行順序(例如課程表問題)

算法流程

  1. 統計所有點的入度,並初始化拓撲排序序列為空。
  2. 將所有入度為0的點,放到如BFS初始的搜索隊列中。
  3. 將隊列中的點一個一個釋放出來,把訪問其相鄰的點,並把這些點的入度-1.
  4. 如何發現某個點的入度為0時,則把這個點加入到隊列中。
  5. 當隊列為空時,循環結束。

算法實現

class Solution():
    def top_sort(self, graph):
        node_to_indegree = self.get_indegree(graph)
        # 初始化拓撲排序序列為空
        order = []
        start_nodes = [node for node in graph if node_to_indegree[node] == 0]
        
        queue = collection.deque(start_nodes)
        while queue:
            head = queue.popleft()
            order.append(node)
            for neighbor in head.neighbors:
                node_to_indegree[neighbor] -= 1
                if node_to_indegree[neighbor] == 0:
                    queue.append(neighbor)
        return order
        
    def get_indegree(self, graph):
        node_to_indegree = {x: 0 for x in graph}
        for node in graph:
            for neighbor in node.neighbors:
                node_to_indegree[neighbor] += 1
        return node_to_indegree


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM