[英]BFS (Breadth First Search) Algorithm in Java -> Cannot implement bfs by not getting node's siblings
我有一個關於從主節點獲取所有兄弟節點並實現Java編寫的進程n廣度優先搜索算法的問題。
我該如何實施?
我分享了如下所示的代碼片段。
這是我的節點 class,如下所示。
public class Node{
Node(int data){
this.data = data;
this.left = null;
this.right = null;
this.visited = false;
}
int data;
Node left;
Node right;
boolean visited;
// getter and setter
}
這是下面顯示的初始化過程。
Node node1 = new Node(1);
Node node7 = new Node(7);
Node node9 = new Node(9);
Node node8 = new Node(8);
Node node2 = new Node(2);
Node node3 = new Node(3);
node1.left = node7;
node1.right = node9;
node7.right = node8;
node9.right = node3;
node9.left = node2;
這是下面顯示的方法。
public static void bfs(Node root){
if (root == null){
return;
}
Node temp; //a binary tree with a inner generic node class
Queue<Node> queue = new LinkedList<>(); //can't instantiate a Queue since abstract, so use LLQueue
queue.add(root);
root.visited = true;
while (!queue.isEmpty())
{
temp = queue.poll(); //remove the node from the queue
// How can I get all siblings of the node like
// for (Node sibling : temp.getSiblingNodes())
// sibling.visited=true;
// queue.add(sibling);
}
// get the result as a list
}
您不應該嘗試獲取節點的兄弟節點。 如果將當前節點的子節點推送到隊列中,您將保證按兄弟順序將它們拉出隊列。 這里重要的是當一個節點從隊列中被拉出時你訪問它,而不是當它被添加到隊列中時。
所以你的 function 可以變成這樣:
public static List<Node> bfs(Node root){
Queue<Node> queue = new LinkedList<>();
List<Node> result = new ArrayList<>();
if (root == null){
return result;
}
queue.add(root); // Don't visit this root node yet...
while (!queue.isEmpty())
{
Node node = queue.poll();
result.add(node); // Here we visit the node
// Add the children of the visited node to the queue
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
return result;
}
調用者可以這樣做:
for (Node node : bfs(node1)) {
System.out.println(node.data);
}
由於Node
有一個屬性isVisited
,我假設圖中可能存在循環。
該算法可以描述為以下步驟:
將root
標記為已訪問並將其放入隊列。
然后直到Queue不為空,重復:
current
Node);left
right
節點。 如果一個子節點存在(即不是null
)並且還沒有被訪問過,那么將這個節點添加到隊列和兄弟節點的結果列表中,並將子節點的isVisited
屬性設置為true
。這就是它可能的實現方式:
public static List<Node> bfs(Node root) {
if (root == null) return Collections.emptyList();
List<Node> siblings = new ArrayList<>();
Queue<Node> queue = new ArrayDeque<>(); // performs better than LinkedList
queue.add(root);
// siblings.add(root); // uncomment this line ONLY if you need the root-Node to be present in the result
root.visited = true;
while (!queue.isEmpty()) {
Node current = queue.poll();
tryAdd(siblings, queue, current.left);
tryAdd(siblings, queue, current.right);
}
return siblings;
}
public static void tryAdd(List<Node> siblings, Queue<Node> queue, Node next) {
if (next != null && !next.isVisited()) {
queue.add(next);
siblings.add(next);
next.setVisited(true);
}
}
為了避免right
left
節點重復相同的操作,我創建了方法tryAdd()
。
我們可以通過引入Predicate
來改變其條件邏輯(在這種情況下,條件很短且可讀性強,並且顯示此選項是為了教育目的):
public static final Predicate<Node> IS_NULL_OR_VISITED =
Predicate.<Node>isEqual(null).or(Node::isVisited);
public static void tryAdd(List<Node> siblings, Queue<Node> queue, Node next) {
if (IS_NULL_OR_VISITED.test(next)) return;
queue.add(next);
siblings.add(next);
next.setVisited(true);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.