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

发布于 2024-10-20 07:54:42 字数 2673 浏览 1 评论 0 原文

我已经尝试了一段时间让这个图表伪装成二叉树工作。目前我正在使用一个函数,该函数传入根节点和我正在查找的节点的 ID。唯一的问题是,根据我的编码方式,我的一侧永远无法超过 3 个节点长。我确信我只是没有正确执行递归。我已经被这个问题困住了一晚上了,没能明白。我尝试查看其他图表和树,但无济于事。我们没有使用实际的顶点或其他类似图形的属性,但我不能只使用 if (x then root.left,因为这不成立因为它仍然是一个“图”,

这是我的非工作搜索算法,如果我将其设置为几个节点长,它就会在右侧停止工作。访问的是使用 HashSet() 类。

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

  if (lc.getID()==id)
      return lc;
  if(rc.getID()==id)
      return rc;
  return null;
}

我有一个用于打印所有树的工作代码,但我无法更改上面代码中的关键比较。

private String dfsPrint(Node x) //pass in root at top level
                                //returns a String containing all ID's
{
   if (x==null) //base case. Runs into null link
       return "";
   if(visited.contains(x.getID())) //visited before
       return "";
   visited.add(x.getID()); //don't go below Node again
   String lc = dfsPrint(x.getLeftChild()); //recursive stuffs
   String rc = dfsPrint(x.getRightChild());
   return Integer.toString(x.getID()) + " " + lc + rc;
}

感谢您的帮助。

编辑:我想我会扩展我正在做的事情。我必须有一个函数 makeRight 或 makeLeft 来放入一个新节点,然后现有节点放入它的左子节点或右子节点。 就是这样。其中search是调用私有dfs的公共方法。

  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);

}

根据我如何订购 lc 和 rc 的递归函数 if 语句,树的另一侧会递归回到基本情况,这让我假设 dfs 方法出了问题。这是请求的节点类。

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

}

I have been trying for a while to get this Graph disguised as a Binary Tree working. Currently I'm using a function that passes in the root node and the ID of the node I am looking for. Only problem is that depending on how I code it, one of my sides can never get past 3 nodes long. I'm sure I'm just not doing the recursion correctly. I've been stuck on this all night, and can't get this. I've tried looking at other graphs and trees, to no avail. We aren't using actual vertexes or other graph like properties, but I can't just use if (x <root.getID()) then root.left, because that doesn't hold up since it is still a "graph"

Here is my non working search algorithm that stops working on the right side if I make it a few nodes long. Visited is using the HashSet() class.

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

  if (lc.getID()==id)
      return lc;
  if(rc.getID()==id)
      return rc;
  return null;
}

I have a working code for printing all of the tree, but I can't get it to change for the key comparison in the above code.

private String dfsPrint(Node x) //pass in root at top level
                                //returns a String containing all ID's
{
   if (x==null) //base case. Runs into null link
       return "";
   if(visited.contains(x.getID())) //visited before
       return "";
   visited.add(x.getID()); //don't go below Node again
   String lc = dfsPrint(x.getLeftChild()); //recursive stuffs
   String rc = dfsPrint(x.getRightChild());
   return Integer.toString(x.getID()) + " " + lc + rc;
}

Thank you for any help.

Edit: I suppose I will expand on what I am doing. I have to have a function makeRight or makeLeft that puts in a new node, and then an existing node puts it has its left or right child.
Here is that. In it search is the public method that calls the private dfs.

  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);

}

Depending on how I order the recursive functions if statements for lc and rc, a different side of the tree gets recursed back up to the base case, which is what makes me assume the dfs method is what is wrong. Here is the requested node class.

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明天过后 2024-10-27 07:54:42

你可以简化代码。我认为你不需要“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());
}

you could simplify the code. I don't think you need 'id'. how about this?

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());
}
昔梦 2024-10-27 07:54:42

在某些情况下,您的 dfs 方法会返回 null。当您尝试对此类返回值调用 getId() 时,您应该会收到异常。你不是吗?

Your dfs method returns null in several cases. When you try to call getId() on such a returned value, you should get an exception. Don't you ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文