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

Posted

技术标签:

【中文标题】二叉搜索和二叉搜索树的区别?【英文标题】:Difference between binary search and binary search tree? 【发布时间】:2014-02-05 18:57:42 【问题描述】:

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

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

【问题讨论】:

二叉搜索是一种算法,二叉搜索树是一种数据结构。见binary search tree 和binary search algorithm。 @KenWhite 我同意您对差异的评论;不过,我认为值得指出的是,当您 某物上执行二分搜索时,您隐含 将该某物视为二叉搜索树。即,差异主要是界面之一。 【参考方案1】:

二叉搜索树

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

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】:

不,它们不一样。

Binary search tree:

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

Binary search:

一种算法,适用于已排序的数据结构(通常但不一定是数组),并且在每一步中,查看中间的值并递归到左侧或对,取决于目标值是小于还是大于中间的值(如果相等则停止)。

当然,data structure 是:

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

而algorithm 是:

一步一步的计算过程。

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

【讨论】:

二叉搜索是一种算法,但请注意,您可以轻松地将其表述为在二叉树上运行:“一种适用于二叉搜索树的算法,并且在每一步都查看根处的值并向左或向右递归,具体取决于目标值是小于还是大于根处的值,或者停止它是相等的)。那么,二叉搜索树实际上只是某些数据的一种接口表示。排序后的数组可以表示为二叉搜索树:“根值”只是...的中间元素。 …数组,左子树是根左边的子数组,右子树是根右边的子数组。 @JoshuaTaylor 你评论的第一部分正是我在最后一段中想要表达的。【参考方案3】:

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

二叉搜索树:

搜索θ(log(n))不平衡的最坏情况(O(n)) > 英国夏令时,

插入节点:θ(log(n))不平衡(O(n)) /em>英国夏令时

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

平衡二叉搜索树:

搜索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) 将较大的数组项移动到相邻的左侧)

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

【讨论】:

请为 BST 添加:log n,因为树是平衡的。 为什么用 log(n) + O(n) ( O(log(n)) 来查找删除位置你是怎么计算出来的? 我已经重新格式化了答案。为了找到一个值的删除位置,它可以在这个排序数组上进行二进制搜索,这将是 O(log(n))。【参考方案4】:

    要使用二进制搜索来搜索元素,元素应该在顺序内存位置中表示,例如使用数组,您需要知道数组的大小才能找到中间元素 要使用二叉搜索树进行搜索,我们不需要顺序位置的数据..我们需要将元素添加到 BST 节点中......每个 BST 节点都包含其左右子节点,因此知道根就足以在树

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

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

    现在来看看搜索时间复杂度..

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

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

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

    李>

【讨论】:

以上是关于二叉搜索和二叉搜索树的区别?的主要内容,如果未能解决你的问题,请参考以下文章

说一下B+tree和二叉搜索树的区别?说一下二叉搜索树和AVL树红黑树之间的差别

二叉树和二叉搜索树

Treap——堆和二叉树的完美结合,性价比极值的搜索树

C++二叉树进阶(二叉搜索树,KV模型)

C++二叉树进阶(二叉搜索树,KV模型)

数据结构—二叉树如何删除一个结点二叉树排序树和二叉搜索树的遍历