定义
1、二叉查找树树中的任一节点,其左子树的节点都小于该节点,其右子树的节点都大于该节点
2、二叉查找树支持快速查找、插入、删除
查找、插入、删除
1、查找:
(1)递归查找,若要查找的节点p值大于root的值,则在其右子树进行递归查找,反之则在其左子树进行递归查找。
(2)时间复杂度:在O(logn)~O(n)之间,最好是O(logn),此时树为完全二叉树;最坏为O(n),此时树退化为了链表
2、插入:
(1)一般插入在叶子节点。先递归查找,比较要插入的节点p与已存在节点的大小关系。
若p>root,则p应插入在root的右子树,若root的右子树为空,则p直接插入在该右子树即可,若不为空,则还需递归root的右子树。
若p<root,则p应插入在root的左子树,若root的左子树为空,则p直接插入在该左子树即可,若不为空,则还需递归root的左子树。
(2)时间复杂度:O(logn)~O(n)
3、删除:
(1)若删除的节点为叶子节点,直接删除即可。
(2)若删除的节点p只有一个子节点q,将p的父节点直接指向q
(3)若删除的节点p有两个子节点,则找到p的右子树中的最小节点q,将p、q的位置互换,此时p被放在了叶子节点中,此时直接删除p即可。
(4)时间复杂度:O(logn)~O(n)
支持重复数据的二叉查找树
如何存储有重复数据的二叉查找树呢?两种方法:
1、节点中存储的是链表或者支持动态扩容的数组,将相同的数据都放在同一个节点中
2、一个节点只存储一个数据,遇到某个节点q的值与要插入的节点p值相同,则将p插入在q的右子树中。查找时,把所有相等的值都找出来,直至遇到叶子节点停止查找。
散列表与二叉查找树
1、散列表是无序存储,需输出有序数据必须得进行排序,而二叉查找树的中序遍历可以遍历出有序数据
2、散列表扩容耗时大,且不可避免的存在哈希冲突。相比较而言,常用的二叉查找树的性能稳定,大部分时候稳定在O(logn)
图源:王争——数据结构与算法之美