搜索二叉树

发布于 2024-07-26 11:40:24 字数 1416 浏览 3 评论 0原文

我正在编写一个迭代函数来在二叉树中搜索特定值。 在我了解如何泛化类之前,它被本地化为有符号整数。

假设我的类是 BinarySearchTree,它有一个指向树的根节点的指针。 还假设节点是通过插入函数插入的,并且具有指向两个子节点的指针。 这是 Node 结构的一个简化版本:

struct Node
{
   public:
      Node *left_, *right_;
      int value_

      Node(int val) : value_(val), left_(0), right_(0) { }
      //done in this manner to always make sure blank children are
      //init to zero, or null
      Node(int val, Node *left, Node *right) : value_(val), left_(0), right_(0) 
          { left_ = left; right_ = right; } 
}

因此,您可以安全地假设节点的 uninit 指针将为 NULL。

这是我的代码:

int BinarySearchTree::search(int val)
{
    Node* next = this->root();

    while (next->left() != 0 || next->right () != 0)
    {
        if (val == next->value())
        {
            return next->value();
        }    
        else if (val < next->value())
        {
            next = next->left();   
        }
        else if (val > next->value())
        {
            next = next->right();
        }
    } 

    //not found
    return 0;
}

此代码被朋友拒绝,原因有两个:

1)如果 next 没有子节点,则两者的计算结果都为零,我将过早退出循环(我永远不会根据 next 的值检查搜索到的 val)。

2)如果next有一个孩子,但你要查找的数据应该在树的空一侧,next将被设置为0,并且它会再次循环,左右比较next(即0)像 while(0->left()) 这样的树,导致未定义的行为。

有人告诉我,这两个问题的解决方案在于循环条件,但我不知道我能做些什么来轻松解决这种情况。 Stack Overflow 社区可以提供一些见解吗?

I'm writing an iterative function to search a binary tree for a certain value. This is localized to signed ints until I get into how to genericize classes.

Assume that my class is BinarySearchTree, and it has a pointer to the root node of the tree. Also assume that nodes are inserted through an insert function, and have pointers to two children. Here is a much abbreviated version of the Node struct:

struct Node
{
   public:
      Node *left_, *right_;
      int value_

      Node(int val) : value_(val), left_(0), right_(0) { }
      //done in this manner to always make sure blank children are
      //init to zero, or null
      Node(int val, Node *left, Node *right) : value_(val), left_(0), right_(0) 
          { left_ = left; right_ = right; } 
}

So, you can safely assume that a node's uninit pointers will be NULL.

Here is my code:

int BinarySearchTree::search(int val)
{
    Node* next = this->root();

    while (next->left() != 0 || next->right () != 0)
    {
        if (val == next->value())
        {
            return next->value();
        }    
        else if (val < next->value())
        {
            next = next->left();   
        }
        else if (val > next->value())
        {
            next = next->right();
        }
    } 

    //not found
    return 0;
}

This code is being rejected by a friend for two reasons:

1) If next has no children, both will evaluate to zero and I will prematurely exit the loop (I will never check the searched val against next's value).

2) If next has one child, but the data you are searching for should be on the empty side of the tree, next will be set to 0, and it will loop again, comparing next (which is 0) to the left and right trees like while(0->left()), resulting in undefined behavior.

I am told that the solution to both problems lies in the loop condition, but I can't see what I can do to easily remedy the situation. Can the community of Stack Overflow offer any insights?

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

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

发布评论

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

评论(3

夏了南城 2024-08-02 11:40:24

我认为你应该测试循环中的 next 是否不为 NULL,如下所示:

int BinarySearchTree::search(int val)
{
    Node* next = this->root();

    while (next)
    {
        if (val == next->value())
        {
            return next->value();
        }    
        else if (val < next->value())
        {
            next = next->left();   
        }
        else if (val > next->value())
        {
            next = next->right();
        }
    } 

    //not found
    return 0;
}

I think you should be testing if next is not NULL in your loop like so:

int BinarySearchTree::search(int val)
{
    Node* next = this->root();

    while (next)
    {
        if (val == next->value())
        {
            return next->value();
        }    
        else if (val < next->value())
        {
            next = next->left();   
        }
        else if (val > next->value())
        {
            next = next->right();
        }
    } 

    //not found
    return 0;
}
ˇ宁静的妩媚 2024-08-02 11:40:24

试试这个:

while (next != NULL)

Try this:

while (next != NULL) ?

千笙结 2024-08-02 11:40:24

首先,我不确定你为什么要返回一个 int 。 如果您在树中搜索 0 该怎么办? 您可能想要这样的东西:

bool BinarySearchTree::Search(int val) {
  Node* current = root();
  while (current != NULL) {
    // Check if it's here
    if (val == current->value()) {
      return true;
    }
    if (val < current->value()) {
      current = current->left();
    } else {
      current = current->right();
    }
  }
  // Not found
  return false;
}

请注意循环不变:在每个循环开始时,您位于需要“处理”的非空节点。 首先检查是否是您想要的节点。 如果不是,则创建一个分支,并让循环决定该分支是否“好”(即非空)。 然后您将让下一个循环迭代负责测试。

First of all, I'm not sure why you are returning an int. What if you are searching for 0 in the tree. You probably want something like this:

bool BinarySearchTree::Search(int val) {
  Node* current = root();
  while (current != NULL) {
    // Check if it's here
    if (val == current->value()) {
      return true;
    }
    if (val < current->value()) {
      current = current->left();
    } else {
      current = current->right();
    }
  }
  // Not found
  return false;
}

Notice that the loop invariant: at the beginning of each loop, you are at a non null node that you need to "process". First check if it's the node you want. If not, make a branch, and let the loop decide if the branch was "good" (ie - non null). Then you'll let the next loop iteration take care of testing.

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