我是否能够正确估计O(n)?

时间:2019-03-17 15:24:53

标签: c algorithm time-complexity binary-search-tree

请注意:这个问题与算法的最佳实现无关,与数据结构无关。


给定一个二叉树,需要确认它是bst。 我知道效率更高(O(n))的算法,问题不关乎它。我正在练习我的O估计技能:

int isBST(struct node* node)  
{  
  if (node == NULL)  
    return(true);  

  if (node->left!=NULL && maxValue(node->left) > node->data)  
    return(false);  

  if (node->right!=NULL && minValue(node->right) < node->data)  
    return(false);  

  if (!isBST(node->left) || !isBST(node->right))  
    return(false);  

  return(true);  
}

..假设maxValue(...)/minValue(...)是每个需要O(n)运行的辅助函数。

如果h是“级别”的数量,则它从根开始并以叶子结束。在每个级别,maxValue(...)minValue(...)都在(n - 1) / 2^l范围内被调用,其中l是当前级别。有h个级别,所以我希望得到类似(n - 1) / 1 + (n - 1) / 2 + (n - 1) / 4 + ... + (n - 1) / 2^h的东西。看来O(n * h)是正确的上限,对吗?

请验证我的想法。

1 个答案:

答案 0 :(得分:1)

是的,您是正确的。那是正确的上限。在每个级别上,您将为maxValues进行总体O(n)工作。您可以检查this进行非常类似的运行时分析(由于h = logn假设平衡良好,因此它给出O(nlogn))。使用h是一个很好的选择,如果树完全不平衡(h = O(n)),则运行时将为O(n ^ 2),但是如果树完全平衡(h = O(logn)),则将具有O (nlogn)。

还有一件事,您实际上可以在递归时缓存/计算最大值/最小值,这将为您提供摊销的O(n)运行时:

struct helper {
  int min;
  int max;
};

int isBST(struct node* root) {  
  struct helper help;
  return isBST_internal(root, &help);  
}

int isBST_internal(struct node* root, struct helper *min_max) {
  if (!root) return true;

  if (root->left) {
    // Recurse on left
    struct helper left_helper;
    int is_left_BST = isBST_internal(root->left, &left_helper)

    if (!is_left_BST || left_helper.max > root->data)
      return false;

    min_max->min = left_helper.min;
  } else {
    // If no left subtree, the min value should be the current node value
    min_max->min = root->data;
  }

  if (root->right) {
    // recurse on right side
    struct helper right_helper;
    int is_right_BST = isBST_internal(root->right, &right_helper)

    if (!is_right_BST || right_helper.min < root->data)
      return false;

    min_max->max = left_helper.max;
  } else {
    // If no right subtree, the max value should be the current node value
    min_max->max = root->data;
  }

  // If we have not returned yet it means all conditions for BST are satisfied
  // Also, min_max is properly set now.

  return true
}

这可能不是最干净的解决方案,但肯定会在线性时间运行。加上额外的O(h)空间损失(以将辅助结构保存在函数堆栈上),但无论如何,这种开销在递归时还是正常的。