在Java中实现BFS

10
我是Java的初学者,需要一些帮助。
我正在尝试实现广度优先搜索算法来解决一个益智游戏(安卓上的Unblock Me)。我的GUI已经做好了,但是我在算法方面卡住了。
到目前为止,我可以计算每个块的可用移动次数,这些块应该是根节点的子节点。每个节点(链表)都有每个块的位置,并且所有节点都存储在一个Set中。
现在我需要标记每个节点为已访问,以免陷入无限循环。
如果有任何帮助,我将不胜感激,并请指出我是否对任何事情有误解。
提前致谢 :)
4个回答

9
public void bfs()
{
    // BFS uses Queue data structure
    Queue queue = new LinkedList();
    queue.add(this.rootNode);
    printNode(this.rootNode);
    rootNode.visited = true;
    while(!queue.isEmpty()) {
        Node node = (Node)queue.remove();
        Node child=null;
        while((child=getUnvisitedChildNode(node))!=null) {
            child.visited=true;
            printNode(child);
            queue.add(child);
        }
    }
    // Clear visited property of nodes
    clearNodes();
}

这是Java中广度优先搜索的示例。如果您提供一些代码,我们可以帮助您对其进行适应。请参考以下内容:

这是一个在Java中实现广度优先搜索的示例。如果您提供了相关代码,我们可以帮助您将其适配到您的项目中。


1
如果您在链表上使用Deque接口,您可以轻松地将BFS修改为DFS(如果需要)。http://docs.oracle.com/javase/7/docs/api/java/util/Deque.html - Thomas Jungblut
2
方法 printNode()visited() 定义在哪里?我该如何模拟 visited - user3871

8
public static void bfs(BinaryTree.Node<Integer> root)
{
    BinaryTree.Node<Integer> temp; //a binary tree with a inner generic node class
    Queue<BinaryTree.Node<Integer>> queue = new LinkedList<>(); //can't instantiate a Queue since abstract, so use LLQueue
    if (root == null)
    {
        return;
    }
    queue.add(root);
    while (!queue.isEmpty())
    {
        temp = queue.poll(); //remove the node from the queue
        //process current node
        System.out.println(temp.data);
        //process the left child first
        if (temp.left != null)
        {
            queue.add(temp.left);
        }
        //process the right child after the left if not null
        if (temp.right != null)
        {
            queue.add(temp.right);
        }
    }
}

5
请尝试以下方法:
import java.util.ArrayList;
import java.util.List;

public class TreeTraverse {

    static 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;
    }

    public static void main(String[] args) {
        //The tree:
        //   1
        //  / \
        // 7   9
        // \  / \
        //  8 2 3

        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;
        System.out.println("BFS: ");
        breadthFirstSearch(node1);

    }

    private static void breadthFirstSearch(Node node){
        List<Node> al = new ArrayList<>();
        al.add(node);
        while(!al.isEmpty()){
            node = al.get(0);
            if(node.left != null){
                int index = al.size();
                al.add(index,node.left);
            }
            if(node.right != null){
                int index = al.size();
                al.add(index,node.right);
            }
            System.out.print(al.get(0).data+" ");
            al.remove(0);


        }
    }

}

欲了解更多信息,请访问:https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/TreeTraverse.java


2
al.add(index,node.left); 中,为什么不直接使用 al.add(node.left) 呢?因为 index 总是指向列表的最后一个位置... - Clint Eastwood

1

@ Growler 我无法对aaronman的链接进行评论(声望不够),但visited字段是Node类中的公共字段成员。

public class Node{
     public boolean visited;
     public Object data;
     //other fields

      public Node(Object data){
           this.visited = false;
           this.data = data;
      }
 }

关于打印节点,我认为aaronman只是将节点对象传递给打印方法,然后显示Node类可能保存的任何数据。
public void print(Node node){
     System.out.println(node.data);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接