BFS廣度優先搜索(模板)

廣度優先搜索(BFS)的一個常見應用是找出從根結點到目標結點的最短路徑。

  1. 結點的處理順序是什麼?
    與樹的層序遍歷類似,越是接近根結點的結點將越早地遍歷
    如果在第 k 輪中將結點 X 添加到隊列中,則根結點與 X 之間的最短路徑的長度恰好是 k。也就是說,第一次找到目標結點時,處於最短路徑中
  2. 隊列的入隊和出隊順序是什麼?
    首先將根結點排入隊列。然後在每一輪中,我們逐個處理已經在隊列中的結點,並將所有鄰居添加到隊列中。值得注意的是,新添加的節點不會立即遍歷,而是在下一輪中處理
    結點的處理順序與它們添加到隊列的順序是完全相同的順序,即先進先出(FIFO)。這就是在 BFS 中使用隊列的原因。

Python模板

def BFS(Node root, Node target):
	"""Return the length of the shortest path between root and target node."""
	queue = []
	step = 0
	# initialize
	queue.append(root)
	# BFS
	while queue:
		step += 1
		# iterate the nodes which are already in the queue
		size = len(queue)
		for i in range(size):
			Node cur = queue[0]
			return step if cur == target
			for next in Node.neighbors:
				queue.append(next)
			queue.pop(0)
	return -1  # there is no path from root to target

Java模板

/**
 * Return the length of the shortest path between root and target node.
 */
int BFS(Node root, Node target) {
    Queue<Node> queue;  // store all nodes which are waiting to be processed
    int step = 0;       // number of steps neeeded from root to current node
    // initialize
    add root to queue;
    // BFS
    while (queue is not empty) {
        step = step + 1;
        // iterate the nodes which are already in the queue
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                add next to queue;
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}

有時,確保永遠不會訪問一個結點兩次很重要。否則,可能陷入無限循環。如果是這樣,可以在上面的代碼中添加一個哈希集來解決這個問題。
有兩種情況不需要使用哈希集:

  1. 確定沒有循環,例如,在樹遍歷中;
  2. 確實希望多次將結點添加到隊列中。

Python模板

def BFS(Node root, Node target):
	"""Return the length of the shortest path between root and target node."""
	queue = []
	uesd = set()  # used = {}是創建字典,創建集合用set()
	step = 0
	# initialize
	queue.append(root)
	used.add(root)
	# BFS
	while queue:
		step += 1
		# iterate the nodes which are already in the queue
		size = len(queue)
		for i in range(size):
			Node cur = queue[0]
			return step if cur == targer
			for next in Node.neighbors:
				if next not in used:
					queue.append(next)
					used.add(next)
			queue.pop(0)
	return -1  # there is no path from root to target

Java模板

/**
 * Return the length of the shortest path between root and target node.
 */
int BFS(Node root, Node target) {
    Queue<Node> queue;  // store all nodes which are waiting to be processed
    Set<Node> used;     // store all the used nodes
    int step = 0;       // number of steps neeeded from root to current node
    // initialize
    add root to queue;
    add root to used;
    // BFS
    while (queue is not empty) {
        step = step + 1;
        // iterate the nodes which are already in the queue
        int size = queue.size();
        for (int i = 0; i < size; ++i) {
            Node cur = the first node in queue;
            return step if cur is target;
            for (Node next : the neighbors of cur) {
                if (next is not in used) {
                    add next to queue;
                    add next to used;
                }
            }
            remove the first node from queue;
        }
    }
    return -1;          // there is no path from root to target
}

Reference:
隊列和廣度優先搜索
Python3集合

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章