Java中二叉树/图的深度优先搜索

Java中二叉树/图的深度优先搜索,java,graph,tree,depth-first-search,Java,Graph,Tree,Depth First Search,我已经尝试了一段时间,以使这个图形伪装成一个二叉树工作。目前,我正在使用一个传递根节点和我要查找的节点ID的函数。唯一的问题是,根据我的编码方式,我的一方永远无法通过3个节点。我确信我只是没有正确地执行递归。我整晚都在忙这个,弄不懂这个。我试过看其他的图表和树,但都没有用。我们没有使用实际的顶点或其他类似图形的属性,但我不能只使用if(xYourdfs方法在几种情况下返回null对于这样一个返回值,您应该得到一个异常。不是吗?您的dfs方法在几种情况下返回null。当您尝试对这样一个返回值调用g

我已经尝试了一段时间,以使这个图形伪装成一个二叉树工作。目前,我正在使用一个传递根节点和我要查找的节点ID的函数。唯一的问题是,根据我的编码方式,我的一方永远无法通过3个节点。我确信我只是没有正确地执行递归。我整晚都在忙这个,弄不懂这个。我试过看其他的图表和树,但都没有用。我们没有使用实际的顶点或其他类似图形的属性,但我不能只使用
if(xYour
dfs
方法在几种情况下返回null
对于这样一个返回值,您应该得到一个异常。不是吗?

您的
dfs
方法在几种情况下返回null。当您尝试对这样一个返回值调用
getId()
时,您应该得到一个异常。不是吗?

您可以简化代码。我认为您不需要“id”。这样如何

private dfs(Node x, int id) {
    if (x==null) { //base case. Runs into null link
       return;
    }
    if(visited.contains(x)) { //visited before
       return;
    }
    visited.add(x); //don't go below Node again
    dfs(x.getRightChild());
    dfs(x.getLeftChild());
}

你可以简化代码。我认为你不需要“id”。这个怎么样

private dfs(Node x, int id) {
    if (x==null) { //base case. Runs into null link
       return;
    }
    if(visited.contains(x)) { //visited before
       return;
    }
    visited.add(x); //don't go below Node again
    dfs(x.getRightChild());
    dfs(x.getLeftChild());
}

我正在搜索ID传递到方法中的节点,所以如果我去掉ID,我只会毫无目的地遍历它,我想好了,但是你可以插入:if(ID==x.getID()){return x;}我可以找到的简单方法是私有节点dfs(node x,int-ID){if(x==null){//base case.Runs in null link return null;}if(visted.contains(x)){//visted before return null;}visted.add(x);//不要再到节点下面dfs(x.getRightChild(),id);dfs(x.getLeftChild(),id);if(id==x.getID())返回x;返回null;这也不起作用。我做错了吗?问题:你为什么需要检查节点是否在二叉树中访问?你不需要它。问题中的原始代码有这个检查,这就是为什么它在这里。当第二次调用它时,可能他想要不同的行为?嗯,我是搜索ID传递到方法中的节点,因此如果我去掉ID,我只会毫无目的地遍历它,我想好了,但是您可以插入:if(ID==x.getID()){return x;}我可以将其还原为私有节点dfs(node x,int ID){if(x==null){//base case.Runs in null link return null;}if(visted.contains(x)){//visted before return null;}visted.add(x);//不要再到节点下面dfs(x.getRightChild(),id);dfs(x.getLeftChild(),id);if(id==x.getID())返回x;返回null;这也不起作用。我做错了吗?问题:为什么需要检查节点是在二叉树中访问的?你不需要它。问题中的原始代码有这个检查,这就是为什么它在这里。当第二次调用它时,他可能想要不同的行为?是的,那就是是正确的。我得到了预期的nullPointerException,但我真的不确定如何测试它,因为我遇到问题的函数生成一个节点,然后将其设置为一个已经存在的节点的左或右子级。我想我只是没有看到递归是如何工作的,因为我正在使用的任何输入都不应该命中null如果这能正常工作。编辑:我可以确认我遇到的空值是基本情况下的空值。是的,这是正确的。我得到了预期的nullPointerException,但我真的不确定如何测试它,因为我遇到问题的函数会生成一个节点,然后将其设置为已存在节点的左或右子级。我不知道hink我只是没有看到递归是如何工作的,因为如果它正常工作,我使用的任何输入都不应该碰到null。编辑:我可以确认我碰到的null是基本情况下的null。递归逻辑本身应该工作得很好,即使您检查lc.getId()==id和co非常令人困惑。函数唯一的返回值是id正确或为null的节点。您的问题似乎在其他地方。可能包括您的节点类?如果它是二叉树(因为它只有两个子树),也是如此您不需要hashmap,但这也不应该是问题所在-尽管我们需要确保实现。我编辑了原始版本,所以如果您还需要什么,请告诉我。再次感谢您的帮助。递归逻辑本身应该可以正常工作,即使您检查了lc.getId()==id和co非常令人困惑。函数唯一的返回值是id正确或为null的节点。您的问题似乎在其他地方。可能包括您的节点类?如果它是二叉树(因为它只有两个子树),也是如此您不需要hashmap,但这也不应该是问题所在-尽管我们需要实现来确保。我编辑了原始版本,所以如果您还需要其他内容,请告诉我。再次感谢您的帮助。
  Node search(int id) // calls private dfsSearch() returns null or a ref to 
                    // a node with ID = id
{
  int ID = id;
  Node x= dfs(root, ID);
  return x;
}


void ML(int x, int y) // ML command
{
visited.clear();
Node temp = new Node(y, null, null);
Node current = search(x);
current.putLeft(temp);

}

void MR(int x, int y)//MR command
{
visited.clear();
Node temp = new Node(y, null, null);
Node current = search(x);
current.putRight(temp);

}
 class Node {
 private int ID; //ID of the Node. Distinct
 private Node leftChild;
 private Node rightChild;

 Node(int identification)//constructor

{
     ID = identification;
}
 Node(int identification, Node lt, Node rt) //constructor

{
 ID = identification;
 leftChild = lt;
 rightChild = rt;

}

int getID()

{
    return ID;
}

Node getLeftChild()
    {
           return leftChild;
    }
Node getRightChild()
{
    return rightChild;
}
void putLeft(Node lt)
{
    leftChild = lt;
}
void putRight (Node rt)
{
    rightChild = rt;
}
private dfs(Node x, int id) {
    if (x==null) { //base case. Runs into null link
       return;
    }
    if(visited.contains(x)) { //visited before
       return;
    }
    visited.add(x); //don't go below Node again
    dfs(x.getRightChild());
    dfs(x.getLeftChild());
}