基本结构
1.叶节点key的数量为[(n-1)/2]上取整到n-1
非叶节点key的数量为[n/2]上取整到n
2.叶节点最后一个指针指向了后面一个叶,非叶节点指针指向了一个孩子
3.非页节点的key是右子树的最小key
4.n指的是指针的个数,不是节点的个数
插入
1.直接按照叶节点插入,看是否分裂
2.如果是叶节点分裂,直接裂开节点,把裂开后右节点最小的key插入父节点
3.如果是非节点的分裂,如果key是奇数,直接把中间一个key插入到父节点,两侧裂开。
如果key是偶数,则平分以后,把左侧最大key插入父节点,在左节点删除这个key。
删除
1.直接删除,看是叶子的key是否少于一半
2.如果同辈的节点大于一半,则转移一个到该节点。可能需要到父节点修改key
如果没有同辈满足条件,那么和某一个同辈合并,更新父节点。
树key数量
假如最大指针数量为m,树高度为h,key数量为n
最小值 | 最大值 | |
---|---|---|
叶节点key | [ m − 1 2 ] [\frac{m-1}2] [2m−1] | m-1 |
非叶节点孩子 | [ m 2 ] [\frac m2] [2m] | m |
n个key树高度 | [ log m [ n m − 1 ] ] + 1 [\log_m[\frac{n}{m-1}]]+1 [logm[m−1n]]+1 | [ log [ m 2 ] [ 2 n m − 1 ] ] + 1 [\log_{[\frac m2]}[\frac{2n}{m-1}]]+1 [log[2m][m−12n]]+1 |
高为h树的key | ( [ m 2 ] ) h − 1 ⋅ [ m − 1 2 ] ([\frac{m}{2}])^{h-1}\cdot [\frac {m-1}2] ([2m])h−1⋅[2m−1] | m h − 1 ( m − 1 ) m^{h-1}(m-1) mh−1(m−1) |
记忆方法:首先计算叶子有几个,计算方法是key除以叶子最大key个数。然后是按照非叶节点孩子数为底数取对数+1
注意按照要求选取叶节点和非叶节点key的个数即可。
计算size就是一层一层算上去。每一层是下一层的1/m倍,m是非叶节点孩子个数。叶子个数还是按照上面算。
缓存替换
LRU:和队列差不多,新页放在后面,如果满了就把第一个旧页删掉
MRU:和栈差不多,新页放在前面
注意,每访问一次缓存,都必须把访问的放入最前面,如果它在缓存中也必须这么做。这个和sply树很像。
每插入一次:总是从根读到需要插入的节点,然后插入。如果需要拆分,那么肯定需要再读一次父节点。
每删除一次:总是从根读到需要删除的节点,然后删除。如果需要合并,那么