1. BST(二叉搜索树),AVL(平衡二叉树)、RBT(红黑树)
二叉查找树(BST)
左结点小于根节点,右结点大于根节点的一种排序树,也叫二叉搜索树。也叫BST,英文Binary Sort Tree。
二叉查找树比普通树查找更快,查找、插入、删除的时间复杂度为O(logN)
。
但是极端的情况,就是会变成一种线性链表似的结构。此时时间复杂度就变成了O(N)
,为了解决这种情况,出现了二叉平衡树。
平衡二叉树(AVL)
全称平衡二叉搜索树,也叫AVL树。是一种自平衡的树。
AVL树也规定了左结点小于根节点,右结点大于根节点。并且还规定了左子树和右子树的高度差不得超过1。这样保证了它不会成为线性的链表。
AVL树的查找稳定,查找、插入、删除的时间复杂度都为O(logN)
,但是由于要维持自身的平衡,所以进行插入和删除结点操作的时候,需要对结点进行频繁的旋转。
如果搜索的次数远远大于插入和删除,那么选择AVL树。
红黑树(RBT)
红黑树也叫RBT,RB-Tree。是一种自平衡的二叉查找树,它的节点的颜色为红色和黑色。它不严格控制左、右子树高度或节点数之差小于等于1。也是一种解决二叉查找树极端情况的数据结构。
红黑树规定了:
- 1.节点是红色或黑色。
- 2.根节点是黑色。
- 3.每个叶子节点都是黑色的空节点(NULL节点)。
- 4 每个红色节点的两个子节点都是黑色。也就是说从每个叶子到根的所有路径上不能有两个连续的红色节点)。
- 5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
红黑树是保持“黑平衡
”的二叉树。
对于黑平衡是指,从根节点开始搜索,一直搜索到叶子节点,所经历的黑色节点的个数是一样的。
时间复杂度是O(logn)
,最大高度:2logn
.红黑树不会像二分搜索树一样退化为链表。
查找的时间上面会比AVL树慢一点,因为最大高度为2logn
,添加操作和删除操作比AVL树要快一些。因为:红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。
RBT对比ALV
AVL 和RBT 都是二叉查找树的优化。其性能要远远好于二叉查找树。
- 结构对比: AVL的结构高度平衡,RBT的结构基本平衡。平衡度AVL > RBT.
- 查找对比: AVL 查找时间复杂度最好,最坏情况都是
O(logN)
。 - 插入删除对比: 1. AVL的插入和删除结点很容易造成树结构的不平衡,而RBT的平衡度要求较低。因此在大量数据插入的情况下,RBT需要通过旋转变色操作来重新达到平衡的频度要小于AVL。
- 如果数据分布较好,则比较宜于采用 AVL树(例如随机产生系列数),但是如果你想处理比较杂乱的情况,则红黑树是比较快的。
2.HashMap
HashMap 的底层数据结构是哈希表(散列表),具体实现为数组+链表(JDK1.8前)或数组+链表+红黑树(JDK1.8及以后)
主要特点:
- 数组:用于存储桶(Bucket)的数组,每个桶要么存储一个元素(键值对),要么存储一个指向链表头结点的引用(哈希冲突时)
- 链表:用于解决哈希冲突,的那个多个键值对银蛇到数组的同一位置时,会形成一个链表。
- 红黑树:联保长度超过某个阈值(默认为8),链表会转换为红黑树以提高查找效率。红黑树是自平衡的二叉查找树,能保持较低的高度,从而减少查找时间。
将每一个字符串元素通过Hash计算索引位置,存放到数组中。
在字符串存放到数组的过程,如果遇到相同的元素,使用链表进行链接。
在计算索引Hashcode的过程中使用扰动函数
使用扰动函数就是为了增加随机性,让数据元素更加均衡的散列,减少碰撞。
哈希表
hash函数就是根据key计算出应该存储地址的位置,而哈希表是基于哈希函数建立的一种查找表
hash函数设计的考虑因素:
1.计算散列地址所需要的时间(即hash函数本身不要太复杂)
2.关键字的长度
3.表长
4.关键字分布是否均匀,是否有规律可循
5.设计的hash函数在满足以上条件的情况下尽量减少冲突
这个博客对哈希表数据结构有详细介绍 数据结构 Hash表(哈希表)
3.B-树(即B树),B+树
B树
其实是一颗特殊的二叉查找树(binary search tree),是多路搜索树,可以拥有多于2个子节点。
每个节点不止存储一个数据值,每个节点也不止有两个子节点,比起平衡二叉树,它能很大程度减低树的高度,提高树的检索效率。
这种数据结构常被应用在数据库和文件系统的实现上。
一个M阶的B树特点如下:
1.定义任意非叶子结点最多只有M个儿子;且M>2;
2.根结点的儿子数为[2, M];
3.除根结点以外的非叶子结点的儿子数为[M/2, M];
4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
5.非叶子结点的关键字个数=指向儿子的指针个数-1;
6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
8.所有叶子结点位于同一层;
B+树
B+树是B树的变体,也是一种多路搜索树。比起B树,B+树所有的节点数值都会出现在叶子节点中,并且,所有叶子节点组成了一个增序的链表。
小结:
- 二叉搜索树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
- B(B-)树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;
所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中; - B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;
B+树总是到叶子结点才命中;