搜索二叉树

时间:2009-07-11 03:37:59

标签: algorithm binary-tree treenode tree-search

我正在编写一个迭代函数来搜索二叉树中的某个值。这是本地化为签名的整数,直到我开始如何泛化类。

假设我的类是BinarySearchTree,它有一个指向树的根节点的指针。还假设通过insert函数插入节点,并指向两个子节点。这是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没有子节点,则两者都将评估为零,我将过早地退出循环(我永远不会检查搜索到的val与下一个值)。

2)如果next有一个子节点,但是你要搜索的数据应该在树的空面,next将被设置为0,它将再次循环,将next(0为0)与像while(0->left())这样的左右树,导致未定义的行为。

我被告知这两个问题的解决方案都在于循环条件,但我无法看到我能做些什么来轻松地解决这个问题。 Stack Overflow社区能否提供任何见解?

3 个答案:

答案 0 :(得分:2)

我认为你应该测试你的循环中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;
}

答案 1 :(得分:1)

试试这个:

while (next != NULL)

答案 2 :(得分:0)

首先,我不确定你为什么要返回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;
}

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