二叉搜索树和堆很像,都是递归有序的树结构。插入,删除时也都要调整树的结构。
二叉搜索树定义:根节点比左子树大,右子树比根节点大。如此递归。
二叉搜索树不允许重复元素。
二叉搜索树适用场合:需要快速插入,快速查找,同时要保持有序结构。比如TreeSet就用的红黑树实现。
如果单纯快插,快删,用hash表O(1)比二叉搜索树O(logn)快多了。
二叉搜索树结构定义好的话,复杂度可维持在O(logn)水平,但也可能退化到O(N)。
为了防止其退化,有两种思路。这两种思路都是在插入,删除时调整二叉树结构。
一、频率法(伸展树)
试想,如果使用频率高的节点在根节点附近,那每次查找时就大大省时。所以伸展树的思路就是
每次查,增时都把相应节点移到根节点,方便下次查询。查找复杂度可维持在O(logn)。
二、结构法(AVL树 ,红黑树)
结构法是限制树的结构,使其不至于退换到线性树。
AVL树,AVL是给每一个节点增加一个平衡因子,每个节点的平衡因子维持在-1,0,1之间。
通过如此限制,增,查,删复杂度维持在1.44O(logn)。
为了保证这种结构,每次插入,删除都要对树结构进行调整。插入时不必递归到根,但删除时却有可能递归到根节点。这也是AVL的缺陷,删除复杂度略高。
调整是旋转调整,从插入节点,递归向上两次,若平衡因子同号,则单旋,异号,则双旋。总共两大类,四小种。
红黑树
红黑树通过红黑节点限制来维持搜索树高度不失控。
具体定义:
根节点是黑,所有外部节点为黑。(外部节点就是叶节点的空指针节点)
从根节点到外部节点上,所有路径的黑节点个数相同。
从根节点到外部节点的任一路径上,红节点不能连续出现。
为什么红黑树的这三条性质能保证高度不失控?
首先定义黑高度,除了根节点之外的任一路径上黑节点的个数称为树的黑高度(r)。
由于红节点不连续出现,所以树的高度h <= 2r。
又因为黑高度实际上是树的最大完全子树的高度。所以树的总节点$n >= 2^r - 1$.
所以树的高度不超过 2log(n+1)。
这也是红黑树整体复杂度维持在O(logn)级别的原因。
红黑树插入删除也要注意保持红黑性质。也是通过旋转,染色实现的。新增节点必染红。
红黑树的优点在于插入,删除时无需递归到根。所以比AVL略优。不过由于整体高度比AVL高,所以频繁查找时还是AVL好。
不过单纯频繁插,删,查,还是Hash表好。