为什么java中不使用多叉树
怎么样的数据结构能高效定位数据呢?前提是顺序排列
1.二分法
通过二分法每次可以排除一半的选择,这样查询是O(logn)
但是这样的线性存储的话存在不好插入删除的问题,如果插入或者删除元素后面的元素全部都要移动位置
2.非线形且天然适合二分查找的数据结构——二叉查找树
一个节点的左子树的所有节点的都小于这个节点,右子树的所有节点都大于这个节点
查询是O(logn),但是存在最坏情况就是退化成链表,此时查询时间复杂度是O(n)
3.平衡二叉查找树
为了防止二叉查找树的退化,增加了一条限制:左右子树的高度差不能大于1
但是在插入或者删除节点的时候为了保持这种平衡需要进行复杂的旋转操作
4.红黑树
保持了二叉查找树的特性,但是保持的是一种相对平衡不是绝对平衡
查找效率比avl树要稍微差一些,但是保持平衡的操作复杂度要更低
5.多叉树——b树
上面的二叉树都存在一个特点,当数据量很多的时候树的高度会变得很高
这种特点对于要从磁盘读取数据的话非常不合适,要想减少读取磁盘次数可以降低树的高度,一个数据块里多放一些数据
b树是每个节点都存放数据记录,但是对于范围查询的话,b树就可能需要访问多个节点
6.b+树
b+树是只有叶子节点才存放数据,非叶子节点只存放索引,这样非叶子节点可以存放更多的索引,树高也就会更低一些
多叉树的查询效率也是O(logn)
对于需要访问磁盘来查找数据的,多叉树无疑是更好的选择,因为低树高磁盘io次数更少
但是对于内存来说呢?
二叉树和多叉树在查找时间复杂度来说都是O(logn),对于内存来说访问速度不是限制,但是内存资源是会稍微紧张一些的,多叉树的一个数据块中存放多个数据,一个数据块如果太大,容易存在内存碎片,所以内存中更适合单个数据作为一个节点
选择什么样的数据结构往往是看要解决什么样的问题
例如redis中使用的是跳表来作为zset的底层数据结构,跳表我觉得也是一种多叉树的思想,而且是偏向b树的多叉树,从最高层索引不断向下查询。但是跳表的索引是一种随机的体现,因为不是固定的新增一个数据就会增加索引,通过随机创建索引的方式能够极大简化树在保持平衡上的消耗,这也符合redis追求简单高效的设计目标。使用了一些冗余的空间来换时间
对于java中一些数据结构,它们与数据库的主要区别是数据量小,其次java的垃圾回收机制也更支持单数据节点的实现方式,且红黑树的性能和稳定性都很高了,没有必要再设计一种适合java的多叉树了