繁体   English   中英

二叉搜索和二叉搜索树的区别?

[英]Difference between binary search and binary search tree?

二叉搜索和二叉搜索树有什么区别?

他们是一样的吗? 阅读互联网似乎第二个仅适用于树(最多 2 个子节点),二进制搜索不遵循此规则。 我不太明白。

二叉搜索树

二叉树中的节点是一种数据结构,它具有一个元素和对其他两个二叉树的引用,通常称为左子树和右子树。 即,一个节点呈现这样的界面:

Node:
  element  (an element of some type)
  left     (a binary tree, or NULL)
  right    (a binary tree, or NULL)

二叉搜索树是二叉树(即一个节点,通常称为根节点),具有左右子树也是二叉搜索树的性质,并且左子树中所有节点的所有元素都小于根的元素,并且右子树中所有节点的所有元素都大于根的元素。 例如,

     5
    / \
   /   \
  2     8
 / \   / \
1   3 6   9

二分查找

二分搜索是一种在二叉搜索树中查找元素的算法。 (它通常表示为搜索有序集合的一种方式,这是一个等价的描述。我将在后面描述等价。)是这样的:

search( element, tree ) {
  if ( tree == NULL ) {
    return NOT_FOUND
  }
  else if ( element == tree.element ) {
    return FOUND_IT
  }
  else if ( element < tree.element ) {
    return search( element, tree.left )
  }
  else {
    return search( element, tree.right )
  }
}

这通常是一种有效的搜索方法,因为在每一步,您都可以删除一半的搜索空间。 当然,如果你的二叉搜索树的平衡性很差,它可能效率很低(它会降级为线性搜索)。 例如,它在如下树中表现不佳:

3
 \
  4
   \
    5
     \
      6

数组的二分搜索

二分搜索通常作为排序数组的搜索方法出现。 这与上面的描述并不矛盾。 事实上,它强调了一个事实,即我们实际上并不关心二叉搜索树是如何实现的; 我们只关心我们可以获取一个对象并用它做三件事:获取一个元素,获取一个左子对象,并获取一个右子对象(当然,受关于左边元素的约束小于元素,右边的元素更大,等等)。

我们可以用一个有序数组来做这三件事。 对于排序数组,“元素”是数组的中间元素,左子对象是它左边的子数组,右边的子对象是它右边的子数组。 例如,数组

[1 3 4 5 7 8 11]

对应树:

     5
    / \
   /   \
  3     8
 / \   / \
1  4  7   11

因此,我们可以为数组编写一个二进制搜索方法,如下所示:

search( element, array, begin, end ) {
  if ( end <= begin ) {
    return NOT_FOUND
  }
  else { 
    midpoint = begin+(end-begin)/2
    a_element = array[midpoint]
    if ( element == midpoint ) {
      return FOUND_IT
    }
    else if ( element < midpoint ) {
      return search( element, array, begin, midpoint )
    }
    else {
      return search( element, array, midpoint, end )
    }
  }
}

结论

正如经常提到的,二分搜索是指这里介绍的基于数组的算法,而二叉搜索树是指具有某些属性的基于树的数据结构。 但是,二分查找所需的性质和二分查找树所具有的性质使这两个方面成为同一枚硬币。 作为二叉搜索树通常意味着特定的实现,但实际上它是提供某些操作并满足某些约束的问题。 二分搜索是一种算法,它对具有这些操作并满足这些约束的数据结构起作用。

不,它们不一样。

二叉搜索树

  • 树状数据结构
  • 每个节点最多有 2 个孩子
  • 节点的左子树只包含键小于节点键的节点
  • 节点的右子树只包含键大于节点键的节点

二分查找

  • 一种处理排序数据结构(通常但不一定是数组)的算法,并在每一步中查看中间的值并向左或向右递归,具体取决于目标值是否较小或大于中间的值(如果相等则停止)。

当然,数据结构是:

在计算机中存储和组织数据以便有效使用数据的一种特殊方式。

虽然算法是:

计算的分步过程。

二叉搜索树中的搜索过程(我们在树中寻找特定值)可以被认为类似于(或一个实例,取决于您的定义以及您是否使用平衡的 BST)二分搜索,因为这也会查看“中间”元素并根据该值与目标值之间的比较结果向左或向右递归。

对于那些来这里快速检查使用哪个的人。 除了上面发布的答案之外,我还想增加这两种技术操作的复杂性。

二叉搜索树:

搜索θ(log(n))不平衡BST 的最坏情况(O(n))

节点的插入θ(log(n))不平衡BST 的最坏情况(O(n))

删除节点: θ(log(n)) , , 不平衡 BST 的最坏情况(O(n))

平衡二叉搜索树:

搜索: log(n) ,

插入节点: O(log(n))

删除节点: O(log(n))

排序数组的二分搜索:

搜索O(log(n))但是,

插入节点:如果数组是静态分配的并且已经满,则不可能。 否则O(n) ( O(n)用于将较大的数组项移动到相邻的右侧)

删除节点: O(log(n)) + O(n) (因此,查找删除位置需要 O(log(n)) + O(n)将较大的数组项移动到相邻的左侧)

所以根据您的需求,您可以选择是否需要快速插入和删除。 如果您不需要这些,那么将内容保存在排序数组中对您有用,因为与树相比,数组占用的内存更少

  1. 要使用二分搜索来搜索元素,元素应该在顺序内存位置表示,就像使用数组一样,你需要知道数组的大小才能找到要使用二叉搜索树搜索的中间元素,我们不需要顺序的数据位置 .. 我们需要将元素添加到 BST 节点中......每个 BST 节点都包含它的左右孩子,所以知道根就足以在树上进行搜索

  2. 由于您使用数组进行二分查找,因此插入和删除将很容易,但在 BST 中,即使在最坏的情况下,我们也需要遍历树的高度

  3. 要进行二分搜索,我们需要将元素按顺序排列,但 BST 不遵循此规则

  4. 现在来到搜索时间复杂性..

    a) 使用二分查找最坏情况的复杂度是 O(logn)

    b) 使用 BST 最坏情况的复杂度是 O(n),即,如果树是倾斜的,那么它就像一个链表一样工作,我们最终会搜索所有元素(这就是我们需要实现平衡 BST 的原因)

  5. 二分查找需要 O(1) 空间复杂度,因为位置是连续的 .. BST 需要 O(n) 空间每个节点我们需要额外的空间来存储其子节点的指针

暂无
暂无

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

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