二叉查找树图示:
【二叉查找树】是一棵空树 或 具有下列性质的二叉树。
对于任意节点:
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值。
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值。
- 左右子树都是二叉查找树。
- 所有结点的值都不相等。
【插入】
查找被插结点的父亲结点,然后插入。
【删除】
- 若是叶结点就直接删除。
- 若只有左子树或只有右子树,其父亲结点指向该结点的指针改为指向该结点的左(右)子树。
- 若左子树右子树均不为空,用被删结点的右子树的最左结点替代被删结点的位置,并取消这个最左结点原有的父子关系。
【查找】
- 从根结点开始,查询的值如果与结点的值相等,就命中。
- 如果比结点值小,就进入左儿子。
- 如果比结点值大,就进入右儿子。
- 如果左儿子或右儿子的指针为空,则报告找不到相应的关键字。
如果二叉查找树能保持平衡,那么其搜索性能逼近二分查找。
二叉查找树相比于连续内存空间的二分查找的优势(类似于链表相对于数组的优势):插入与删除结点不需要移动大段的内存数据。
但二叉查找树经过多次插入与删除后,有可能导致不同的结构,如下图右图的搜索性能已经是线性的了。
想要保持二叉查找树的性能,应尽可能保持上图左图的结构,即所谓的平衡 问题。
【优化】
- AVL 树。
- 红黑树。
- 树堆。