廣度優先搜索(BFS)的一個常見應用是找出從根結點到目標結點的最短路徑。
- 結點的處理順序是什麼?
與樹的層序遍歷類似,越是接近根結點的結點將越早地遍歷。
如果在第 k 輪中將結點 X 添加到隊列中,則根結點與 X 之間的最短路徑的長度恰好是 k。也就是說,第一次找到目標結點時,處於最短路徑中。 - 隊列的入隊和出隊順序是什麼?
首先將根結點排入隊列。然後在每一輪中,我們逐個處理已經在隊列中的結點,並將所有鄰居添加到隊列中。值得注意的是,新添加的節點不會立即遍歷,而是在下一輪中處理。
結點的處理順序與它們添加到隊列的順序是完全相同的順序,即先進先出(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
}
有時,確保永遠不會訪問一個結點兩次很重要。否則,可能陷入無限循環。如果是這樣,可以在上面的代碼中添加一個哈希集來解決這個問題。
有兩種情況不需要使用哈希集:
- 確定沒有循環,例如,在樹遍歷中;
- 確實希望多次將結點添加到隊列中。
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
}