二叉搜索树
目的:使搜索的复杂度降到对数复杂度
定义
- 左子树key<root 右子树key>root
- key是唯一的
有时多一个leftSize,值为左子树结点个数+1(自己)
删除
-
只有一个树叶,和只有一个子树:直接删,顶上
-
同时有左子树或右子树:用左子树的最大或右子树的最小
- t.element覆盖原来的点,调用的remove点会删除原来子树的root,就相当于调整了
树高
最差:
最好:
平衡二叉树
目的:树高始终保持在对数复杂度
定义
- 树高:从树根到树叶最长的
- 平衡因子:右子树高-左子树高 1 0 -1三种情况
插入
第一个左右:看针对最小不平衡子树的root的位置,第二个左右:看root左右子树内部的位置
-
左的左:右单旋
-
右的右:左单旋
-
左的右:左双旋(左子树左单旋+整体做右单旋)
-
右的左:右双旋(右子树右单旋+整体做左单旋)
删除
中序后继:比他大的最小的数
进行替换后用上面的规则自行调整
最终复杂度得证。
m路搜索树
定义
- 每个内结点有最多7个子节点,和1-6个元素
- 有p个元素的结点有p+1个子节点
- p个元素从小到大排列
插入
如果满了插到现有的子节点,再补上空的子节点。注意这里不是B树,不需要保持叶结点在同一行,所以可以往下插。
删除
用中序前驱或中序后继代替。
前驱:
后继:
高度
B树
定义
- 对节点个数更严苛的要求
- 每个叶结点都在同一层上
插入
做题时把m阶B树对应的根和非根结点的children和key的大小限制列出来,如果超出限制则分裂结点,取中间元素上移(若为偶数则随意),最坏是分裂到根节点,生成新的根节点,高度增加1。
删除
-
若为中间结点:删除后上移左孩子最右或右孩子最左(中枢前驱或后继),则相当于叶结点被删除了一个,沿用下面的规则。
-
若为叶子结点:
-
若删除后key>=ceil(m/2)-1,则直接删除,不做更多处理。
-
若删除后key<ceil(m/2)-1,则有两种情况:
-
邻居节点丰满(key>ceil(m/2)-1),则向父节点借一个,再将丰满的兄弟节点的最前或最后上移。
-
邻居节点均不丰满,下移父节点再合并。
-
-
实际操作中要灵活根据规则来,乱变都行。
作业中的实例:
相邻均不丰满,父节点下移再合并。
主要是按照定义灵活变的。
代码实现
只记录s个key值和s+1个children指针,不记录父节点和同级结点。
练习
注意B树关键字可以升序或降序。
叶结点应该不相连?指针指向子树根节点。
错因:只考虑了比左子节点值大比右子结点值小两个条件。必要而非重要要看前驱后继
思路一代码:得到遍历结果,保证后面的数均大于前面的数
注意调用next()时itr会后移
题目是在比大小,把S找清楚即可
思路从最小结点个数=左子树结点个数+右子树结点个数+root入手。
所以可得:
换成>=号,这里的h与n的对应关系更直观。
参考资料(不妥删):
https://www.cnblogs.com/lianzhilei/p/11250589.html
https://www.manongdao.com/article-2436159.html