在Java中很多对象都使用了红黑树的数据结构,比如TreeMap,HashMap(1.8)等。然后我就想看看为什么要使用这种数据结构?
要想了解红黑树,就先看看二叉查找树是什么?
二叉查找树
二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n).
红黑树
二叉树若退化成了一棵具有n个结点的线性链后,则此些操作最坏情况运行时间为O(n)。
后来就出现了红黑树的结构,来使树相对平衡,最终插入,查找、删除的时间复杂复杂度最坏的情况是O(log n)
红黑树(),本质上来说就是一棵二叉查找树,但它在二叉查找树的基础上增加了着色和相关的性质使得红黑树相对平衡,从而保证了红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。
下面是红黑树的定义:https://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91#/media/File:Red-black_tree_example.svg
- 节点是红色或黑色。
- 根是黑色。
- 所有叶子都是黑色(叶子是NIL节点)。
- 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
- 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
因为每一个红黑树也是一个特化的二叉查找树,因此红黑树上的只读操作与普通二叉查找树上的只读操作相同。
然而,在红黑树上进行插入操作和删除操作会导致不再符合红黑树的性质。恢复红黑树的性质需要少量O(log n)的颜色变更(实际是非常快速的)和不超过三次树旋转(对于插入操作是两次)。虽然插入和删除很复杂,但操作时间仍可以保持为O(log n)次。
总结
红黑树相比二叉查找树在时间复杂度上要提升不少,所以JDK1.8中HashMap在单链表冲突后采用这种方式提高查找插入的效率。
作者:狂奔的熊二