二叉查找树
二叉查找树(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树更合适;
在需要频繁插入删除时,选用红黑树更合适。