Java 在执行广度优先搜索时,访问节点时是否重要?

Java 在执行广度优先搜索时,访问节点时是否重要?,java,graph,tree,breadth-first-search,Java,Graph,Tree,Breadth First Search,我已经为Java中的树编写了以下BFS: public class Node { public int value; public ArrayList<Node> myChildren = new ArrayList<Node>(); public Node(int v) { value = v; } } public Node breadthFirstSearch(Node root, int value) {

我已经为Java中的树编写了以下BFS:

public class Node
{
    public int value;
    public ArrayList<Node> myChildren = new ArrayList<Node>();

    public Node(int v)
    {
        value = v;
    }
}

public Node breadthFirstSearch(Node root, int value)
{
    if(root == null) return null;
    Queue<Node> nodesToVisit = new LinkedList<Node>();
    nodesToVisit.add(root);
    while(nodesToVisit.size() > 0)
    {
        Node currentNode = nodesToVisit.remove();
        if(currentNode.value == value) return currentNode;
        nodesToVisit.addAll(currentNode.myChildren);
    }

    return null;
}
公共类节点
{
公共价值观;
public ArrayList myChildren=new ArrayList();
公共节点(INTV)
{
值=v;
}
}
公共节点宽度优先搜索(节点根,int值)
{
if(root==null)返回null;
Queue nodesToVisit=new LinkedList();
nodesToVisit.add(根目录);
while(nodesToVisit.size()>0)
{
Node currentNode=nodesToVisit.remove();
如果(currentNode.value==value)返回currentNode;
nodesToVisit.addAll(currentNode.myChildren);
}
返回null;
}

我的问题是,如果(currentNode.value==value),那么当我“访问”节点时,它是否重要(在运行时复杂性或其他因素方面)。我可以在将节点从队列中弹出之后或在将其放入队列之前访问该节点。

这有关系吗?这取决于你在做什么

如果树中有多个节点符合搜索条件,则在子节点之前访问父节点,而不是在父节点之前访问子节点,可能会更改搜索返回的节点。这真的会发生吗?这取决于你申请的细节

无论哪种方式,big-O的复杂性都是相同的。根据树和搜索的特征,可能需要以这种或那种方式进行更多操作。(例如,如果50%的搜索是针对存储在根节点中的值,则通过首先访问父节点,代码将运行得更快。)

当搜索“失败”(在树中找不到该值)时,无论您以何种顺序访问节点,执行的操作数都是相同的。

不,这不重要(很多)

你基本上是在谈论这两行的顺序:

if (currentNode.value == value) return currentNode;
nodesToVisit.addAll(currentNode.myChildren);
为了性能和代码的清晰性,尽早返回总是一件好事,所以我会让您的代码保持原样


如果颠倒这些行的顺序,则调用
addAll()
会产生额外的成本,但这一成本可以忽略不计。

我认为这更适合codereview.stackexchange.com如果您一遇到该节点就访问该节点,那么您的搜索权重将更偏向“左”(第一个孩子优先)你的
while
循环最好重述为
do。。。而(!nodesToVisit.isEmpty())
。当然,在循环开始时它从来都不是空的,那么为什么要检查那个不可能的条件呢?@seh我使用一个正常的while循环,因为我觉得它增加了代码的可读性,并且额外评估一次条件不会产生任何明显的影响(只有一些额外的机器指令)……但是,我理解你的观点,我相信你,但这关系到另一种可读性:读者需要理解为什么会有防范条件,合理地预期防范条件可能会出现。如果这些条件似乎无法出现,那么您的程序将受到过度约束,并且接近逻辑不一致。编写循环的另一种方法是,不必费心将根节点添加到队列中,而是提前专门处理它。而是将其添加到队列中,以避免重新启动循环体的一部分。这很好,但是不要做额外的工作来避免代码重复。