平衡二叉树
递归就是把只考虑一层,然后考虑边界条件,就像数学归纳法一样。注意的是不要每回合都算一遍。
1 | public boolean isBalanced(TreeNode root){ |
二叉查找树
左小右大,算法第四版
1 | public class BST{ |
(左倾)红黑树
非平衡二叉树,不平衡的节点的左连接改成红色的,叶节点一定是黑色的,
2-3树(和B树有点相似)中的3节点改为左斜的红色连接。
插入新节点的情况:
- 插入到2节点的尾部:旋转即可
- 3节点分种情况:
- 最大:不用旋转,变色
- 最小:一次旋转,变色
- 中间:先左旋,再右旋,变色
- 变色:左右变黑,头变红
删除:删除的是红色节点,不影响,可以直接删除。如果是黑色,就要进行变换,因此在向下的过程中,需要
2-节点。左右子节点都是黑色
3-节点。左右有一个为红色。
4-节点。左右均为红色。
2-3树变为红黑树,3-节点左倾右倾都一样,通过旋转可以互相转化。
删除最小值的时候:
在向下的过程中,如果为3-节点,及左节点为红色,直接递归一次,如果为2-节点,即h.left.left为黑色,先变色,在判断兄弟节点,如果为2-节点,即h.right.left为黑色(判断兄弟节点,都是left,红黑树是平衡的,h的左节点为2-节点,右节点高度必然大于等于左节点,不会出现空指针异常)。直接变色即可
如果兄弟节点为3-节点,借点,
删除最小值的时候:
向下的过程中,h为3-节点时(h.left为红色)首先右旋,因为最大值在右边,而树是左倾的。然后继续向下。
碰到右侧为2-节点时,左侧也是2-节点时,h.left.left为黑色,变色即可。
h.left.left为红色时,同样借个节点。
删除任意节点时:
如果节点在底部,直接删除即可。
如果节点在中间,与其右子树的最小节点,或者左子树的最大节点与其替换,然后把替换的删除掉就行了。每一步都与删除最值的情况相同,只不过多了判断在左右子树的一步。
- key <h.key 2-节点就根据兄弟节点情况,借点或者变色。3-节点继续递归。
- 与删除最大值的情况相同,
1 | public class RedBlack<Key extends Comparable<key>,Value>{ |