二叉查找树之一:二叉查找树

二叉查找树

二叉查找树(BST)的特性:

  • 1.子树上所有结点的值均小于或等于它的根结点的值。
  • 2.子树上所有结点的值均大于或等于它的根结点的值。
  • 3.左、右子树也分别为二叉排序树。

下图中这棵树,就是一颗典型的二叉查找树:

二叉查找树的查找操作

这样的数据结构,在查找时使用二分查找的思想,查找所需的最大次数等同于二叉查找树的高度。

比如,当我们想在上图查找值为10的结点时:
1.查看根结点9
2.根据二叉查找树左子树小、右子树大的特性,10 > 9,因此值为10的结点只可能在根结点的右子树当中,我们查看右孩子结点13
3.由于10 < 13,因此查看左孩子11
4.由于10 < 11,因此查看左孩子10,发现10正是要查找的结点:

不仅查找,在插入新结点时也运用了同样的思路,通过一层一层比较大小,找到新结点适合插入的位置。

二叉查找树插入操作

递归查询插入。

二叉查找树删除操作

二叉查找树的删除操作可以分成三种情况。

情况1,待删除的结点没有子结点:

上图中,待删除的结点12是叶子结点,没有孩子,因此直接删除即可:

情况2,待删除的结点有一个孩子:

上图中,待删除的结点13只有左孩子,于是我们让左孩子结点11取代被删除的结点,结点11以下的结点关系无需变动:

情况3,待删除的结点有两个孩子:

上图中,待删除的结点5有两个孩子,这种情况比较复杂。此时,我们需要选择与待删除结点最接近的结点来取代它。

上面的例子中,结点3仅小于结点5,结点6仅大于结点5,两者都是合适的选择。但习惯上我们选择仅大于待删除结点的结点,也就是结点6来取代它。

于是我们复制结点6到原来结点5的位置:

被选中的结点6,仅大于结点5,因此一定没有左孩子。所以我们按照情况1或情况2的方式,删除多余的结点6:

二叉查找树的缺陷

但是,二叉查找同样树存在缺陷:在插入、删除的过程中不能保证二叉树始终平衡。

比如:

假设初始的二叉查找树只有三个结点,根结点值为9,左孩子值为8,右孩子值为12:

接下来我们依次插入如下五个结点:7,6,5,4,3。依照二叉查找树的特性,结果会变成什么样呢?

此时的二叉树虽然也符合二叉查找树的特性,但是查找的性能大打折扣,几乎变成了线性。

为了解决这个缺陷,提出了自平衡二叉查找树

两种平衡二叉查找树

自平衡二叉查找树,顾名思义,是在插入和删除的过程中自动保持平衡的二叉查找树。

AVL树:是严格平衡的二叉树,要求每个结点的左右子树高度差不超过1
红黑树:任何一条路径上的长度不超过其他路径长度的2倍
红黑树:

二者相比,AVL树的查找效率更高,但平衡调整的成本也更高。

在需要频繁查找时,选用AVL树更合适;
在需要频繁插入删除时,选用红黑树更合适。

你可能感兴趣的:(二叉查找树之一:二叉查找树)