【问题标题】:How to check if a tree is a BST?如何检查一棵树是否是 BST?
【发布时间】:2019-08-28 22:38:09
【问题描述】:

我必须检查一棵树是否是二叉搜索树。我正在使用一个收集值的临时数组进行中序遍历。我必须检查数组是否按升序排列,如果是,则返回 true:

bool myisBST(Node* node, std::vector<int> v);

bool myisBST(Node* node)
{
    return myisBST(node, std::vector<int>());
}

bool myisBST(Node* node, std::vector<int> v)
{
    if (node)
    {
        if (node->left)
            return myisBST(node->left, v);

        v.push_back(node->data);

        if (node->right)
            return myisBST(node->right, v);
    }

    return std::is_sorted(v.begin(), v.end());
}

当二叉树是这样的:

            50
           /  \
         25    75
        /  \   / \
       1   12 62 -99

如您所见,-99 使它不是二叉搜索树,但它仍然返回 true。我的实现有问题吗?

Demo

【问题讨论】:

  • -99 使它不是二叉搜索树,但它仍然返回 true。您的实施有问题吗?对于可能出错的事情,您有更好的候选人吗?
  • @juanchopanza 又来了?
  • 在调试器中运行你的程序,看看它采用什么执行路径。您的代码永远不会命中 is_sorted 检查
  • 你在问你的实现是否有问题。我在问这是否不是很明显。

标签: c++ binary-tree binary-search-tree


【解决方案1】:

两个问题:

  1. myisBST 中,您通过 传递v,而不是通过引用,因此当您以递归方式传递向量时,对其所做的更改不会改变其值在调用方法中。只需将函数签名更改为 bool myisBST(Node* node, std::vector&lt;int&gt;&amp; v) 即可解决此问题。
  2. 您应该返回的值是向量是否已排序(就像您在方法的最后一行中所做的那样),但是您通过编写return myisBST(node-&gt;left, v);return myisBST(node-&gt;right, v); 提前返回。您实际上对这些方法的返回值并不感兴趣;您只是使用它们来按顺序填充向量。从这两行中删除 return

在这两个修复之后,您的方法就可以工作了。

【讨论】:

    【解决方案2】:

    首先,您可能应该通过引用传递vector,否则每个递归调用都会得到一个副本,因此原始向量可能为空。

    其次,你甚至不需要先创建向量然后做检查,你只需检查每个节点的 BST 属性,即根必须大于左孩子,小于右孩子,例如,

    bool isBST(const Node* root, vector<int>* v) {
      if (!root) { return true; }
    
      bool leftBST = true;
    
      if (root->left) {
        if (root->data > root->left->data) {
          leftBST = isBST(root->left, v);
        } else {
          // the current node violates the BST precondition
          return false;
        }
      }
    
      // push the root
      v->push_back(root->data);
      // return false if left subtree is not a BST
      if (!leftBST) return false;
    
      if (root->right) {
        if (root->data < root->right->data) {
          // return whether or not the right subtree is a BST
          return isBST(root->left, v);
        } else {
          // the current node violates the BST precondition
          return false;
        }
      }
    
      // everything good, this is a BST
      return true;
    }
    

    【讨论】:

      【解决方案3】:

      C++ 程序检查树是否为 BST

      struct Node
      {
          int data;
          struct Node* left, *right;
      };
      
      bool IsBST(Node* ObjNode)
      {
          bool leftBST = false;
      
          bool rightBST = false;
      
          if( ObjNode->left != null && ObjNode-left < objNode->data)
          {
              leftBST = IsBST(ObjNode->left)
          }
          else if( ObjNode->left == null)
          {
              leftBST = true;
          }
      
          else if( ObjNode->left != null  && ObjNode-left >= objNode->data)
          {
              leftBST = false;
          }
      
      
          if( ObjNode->left != null && ObjNode-left < objNode->data)
          {
              rightBST = IsBST(ObjNode->right)
          }
          else if( ObjNode->right == null)
          {
              rightBST = true;
          }
      
          else if( ObjNode->right != null  && ObjNode-right >= objNode->data)
          {
              rightBST = false;
          }
      
      
          return (leftBST && rightBST );
      
      }
      

      【讨论】:

        【解决方案4】:

        在之前的解决方案中,他们保留了一个中序遍历的列表,你真的不需要它,你可以继续检查最后一个遍历的元素并继续前进。

        以下解决方案是fastest

        class Solution {
            int lastval = Integer.MIN_VALUE;
            int count = 0;
            public boolean isValidBST(TreeNode root) {
                if(root == null) return true;
                boolean left = isValidBST(root.left);
                if(!left){
                    return false;
                }
                int rootVal = root.val;
                if(rootVal == -2147483648 && count == 0 ){
                    rootVal = rootVal + 1;
                }
                if( rootVal <= lastval){
                   return false; 
                }
                count ++;
                lastval = root.val;
                boolean right = isValidBST(root.right);
                if(!right){
                    return false;
                }
                return true; 
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-24
          • 2023-03-29
          • 1970-01-01
          相关资源
          最近更新 更多