简体   繁体   English

搜索二叉树

[英]searching a binary tree

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. 这将本地化为带符号的int,直到我了解如何泛化类为止。

Assume that my class is BinarySearchTree, and it has a pointer to the root node of the tree. 假设我的类是BinarySearchTree,它具有指向树的根节点的指针。 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: 这是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; } 
}

So, you can safely assume that a node's uninit pointers will be NULL. 因此,您可以放心地假设节点的uninit指针将为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). 1)如果next没有子对象,则两者都将为零,并且我将过早退出循环(我将永远不会针对next的值检查搜索到的val)。

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. 2)如果next有一个孩子,但是您要搜索的数据应该在树的空侧,那么next将被设置为0,并且它将再次循环,将左右的next(即0)进行比较像while(0->left())这样的树,导致未定义的行为。

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? Stack Overflow社区可以提供任何见解吗?

I think you should be testing if next is not NULL in your loop like so: 我认为您应该像这样在循环中测试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;
}

Try this: 尝试这个:

while (next != NULL) ? while (next != NULL)

First of all, I'm not sure why you are returning an int. 首先,我不确定为什么要返回int。 What if you are searching for 0 in the tree. 如果要在树中搜索0,该怎么办。 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". 请注意,循环不变:在每个循环的开始处,您处在需要“处理”的非null节点上。 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). 如果不是,则创建一个分支,并让循环确定该分支是否为“良好”(即-非null)。 Then you'll let the next loop iteration take care of testing. 然后,让下一个循环迭代进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM