【问题标题】:Largest Subtree Which is a Binary Search Tree (BST)二叉搜索树(BST)的最大子树
【发布时间】:2013-01-08 21:06:38
【问题描述】:

给定一棵二叉树,我想找出最大的子树是 BST 在里面。

此问题与Finding the largest subtree in a BST 重复,其中 1337c0d3r 通过自下而上遍历树给出 O(n) 解决方案。有两行代码让我感到困惑。谁能帮我解释一下?

// Find the largest BST subtree in a binary tree.
// If the subtree is a BST, return total number of nodes.
// If the subtree is not a BST, -1 is returned.
int findLargestBSTSubtree(BinaryTree *p, int &min, int &max,
                   int &maxNodes, BinaryTree *& largestBST) {
  if (!p) return 0;
  bool isBST = true;
  int leftNodes = findLargestBSTSubtree(p->left, min, max, maxNodes, largestBST);
  int currMin = (leftNodes == 0) ? p->data : min;
  if (leftNodes == -1 ||
     (leftNodes != 0 && p->data <= max))
    isBST = false;
  int rightNodes = findLargestBSTSubtree(p->right, min, max, maxNodes, largestBST);
  int currMax = (rightNodes == 0) ? p->data : max;
  if (rightNodes == -1 ||
     (rightNodes != 0 && p->data >= min))
    isBST = false;
  if (isBST) {
    min = currMin;
    max = currMax;
    int totalNodes = leftNodes + rightNodes + 1;
    if (totalNodes > maxNodes) {
      maxNodes = totalNodes;
      largestBST = p;
    }
    return totalNodes;
  } else {
    return -1;   // This subtree is not a BST
  }
}

BinaryTree* findLargestBSTSubtree(BinaryTree *root) {
  BinaryTree *largestBST = NULL;
  int min, max;
  int maxNodes = INT_MIN;   // INT_MIN is defined in <climits>
  findLargestBSTSubtree(root, min, max, maxNodes, largestBST);
  return largestBST;
}

我对以下两行代码感到困惑。按照我的常识,递归遍历左树后,max变量应该会更新,为什么在递归遍历左树之后把int currMin = (leftNodes == 0) ? p-&gt;data : min;放在右边呢?
int currMax = (rightNodes == 0) ? p-&gt;data : max;的同样问题

...
int currMin = (leftNodes == 0) ? p->data : min;
...
int currMax = (rightNodes == 0) ? p->data : max;

【问题讨论】:

  • 您需要的算法非常接近 alpha-beta 搜索。 (除非您需要几乎访问整棵树并且不能修剪)

标签: algorithm data-structures binary-tree binary-search-tree


【解决方案1】:

请记住,此算法自下而上遍历树。访问一个节点的左子树后,以下情况之一为真:

  1. 左子树不是 BST => 当前树不是 BST
  2. 左子树是 BST => 当前树中的最小值是 min
  3. 左子树没有节点 => 当前树中的最小值是当前节点的值

同理,遍历右子树后,当前树中的最大值要么是当前节点的值,要么是右子树中的最大值(max

所以这条线 int currMin = (leftNodes == 0) ? p-&gt;data : min; 测试条件 2 或 3 是否为真,并相应地更新 min 的值,以便该值对于测试树中当前节点上方的节点是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2012-05-13
    • 1970-01-01
    • 2019-04-09
    相关资源
    最近更新 更多