如何更改此“广度优先搜索”代码以使其起作用?

时间:2019-06-10 05:54:58

标签: java

编辑1:其他信息 这段代码的目标是穿过一棵没有价值的树。然后它将输出搜索结果(应该是整个树)。如果需要任何其他信息,请告诉我!

老实说,我真的不知道我在做什么。我正在尝试在此处跟踪这张图片:https://i.imgur.com/FKKyjlV.png

感谢您的帮助。

public static <T> void BFS(TreeNode<T> t, int root){

    ArrayList<Integer> S = new ArrayList<Integer>();
    Queue<Integer> Q = new LinkedList<Integer>();

    S.add(root);
    Q.add(root);

    while (!Q.isEmpty()){
        Q.remove();
    }
    for (TreeNode n : t.getChildren()) {
        if (!S.contains(n)) {
            S.add(n);
            Q.add(n);
        }

    }
}

1 个答案:

答案 0 :(得分:0)

我已经在这里实现了您的算法的有效版本:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class BreadthFirstSearch {

    public static void main(String[] args) {
        //just for testing
        new BreadthFirstSearch();
    }

    public BreadthFirstSearch() {
        //build a TreeNode<T> graph for testing
        TreeNode<Integer> root = new TreeNode<Integer>(1);

        TreeNode<Integer> child_1 = new TreeNode<Integer>(2);
        TreeNode<Integer> child_2 = new TreeNode<Integer>(3);
        TreeNode<Integer> child_1_1 = new TreeNode<Integer>(4);
        TreeNode<Integer> child_1_2 = new TreeNode<Integer>(5);
        TreeNode<Integer> child_2_1 = new TreeNode<Integer>(6);
        TreeNode<Integer> child_2_2 = new TreeNode<Integer>(7);
        TreeNode<Integer> child_1_2_1 = new TreeNode<Integer>(8);
        TreeNode<Integer> child_2_2_1 = new TreeNode<Integer>(9);

        child_1.setChildren(Arrays.asList(child_1_1, child_1_2));
        child_2.setChildren(Arrays.asList(child_2_1, child_2_2));
        child_1_2.setChildren(Arrays.asList(child_1_2_1));
        child_2_2.setChildren(Arrays.asList(child_2_2_1));
        root.setChildren(Arrays.asList(child_1, child_2));

        //now root is a graph like this:

        //              1
        //           /     \
        //          2       3
        //         /  \    /  \
        //        4   5   6    7
        //           /        /
        //          8        9

        //so the breadth first search should lead to the result list: [1, 2, 3, 4, 5, 6, 7, 8, 9]
        List<Integer> breadthFirstSearched = BFS(root);
        System.out.println(breadthFirstSearched);
    }

    /**
     * A simple TreeNode<T> implementation.
     */
    public class TreeNode<T> {

        private List<TreeNode<T>> children;
        private T value;

        public TreeNode(T value) {
            children = new ArrayList<TreeNode<T>>();
            this.value = value;
        }

        public List<TreeNode<T>> getChildren() {
            return children;
        }
        public void setChildren(List<TreeNode<T>> children) {
            this.children = children;
        }

        public T getValue() {
            return value;
        }
        public void setValue(T value) {
            this.value = value;
        }
    }

    public static <T> List<T> BFS(TreeNode<T> root) {//here you just need the root node which also holds the graph in this implementation
        List<T> S = new ArrayList<T>();//here you should use the generic type T (if the TreeNode<T> is a TreeNode<Integer> it will be a List<Integer> on runtime)
        Queue<TreeNode<T>> Q = new LinkedList<TreeNode<T>>();//here you need a queue of TreeNode<T> objects instead of integers

        S.add(root.getValue());
        Q.add(root);

        //this would just remove all elements from the queue before starting the real algorithm
        /*while (!Q.isEmpty()) {
            Q.remove();
        }*/

        //in the pseudocode you provided the code after the while was indented, which means it belongs inside the while loop like this:
        while (!Q.isEmpty()) {
            //here you need to get the first TreeNode<T> from the queue
            TreeNode<T> current = Q.poll();//poll is equal to dequeue here (both get the first element of the queue and remove it from the queue)
            for (TreeNode<T> n : current.getChildren()) {//iterate over all children of the current node
                if (!S.contains(n.getValue())) {//here you need to check the value of n (otherwise you compare TreeNode<T> to T which doesn't make much sense)
                    S.add(n.getValue());
                    Q.add(n);
                }
            }
        }

        //here you should return the created list, otherwise it's no longer available
        return S;
    }
}

由于您没有提供TreeNode类,因此我实现了一个类,因为我认为它可能会起作用。我还添加了一个测试用例,因此您可以运行该示例并查看其工作原理。程序生成的输出像[expeded]是[1、2、3、4、5、6、7、8、9]。

代码遍历树并首先找到“较高”的节点。关于它如何工作的一个很好的例子是在这里:

Breadth first search gif from wikipedia

黑色节点是已添加到树中的节点,灰色节点是已添加到队列中但树未添加的节点,白色节点尚未添加到列表或树中。

可以找到该算法的完整说明here