最好结合《算法》看
区别
AVL树,最大高度差不超过1的平衡二叉搜索树,用于自平衡的计算牺牲了插入删除性能;
B树是平衡多叉树,它的B是人名,不是Balance的意思;
红黑树基本思想是用二叉树表示的2-3树,红链接将两个2节点相连构成3节点
红黑树特点
- 红链接均为左连接;
- 没有一个节点同时和两个红连接相连;
- 完美黑色平衡;
- 根节点全部是黑色;
红黑树的三个基本操作 & 手撕红黑树
旋转,其实是两个节点位置的旋转,《算法》里一开始讲得比较模糊;
首先有一个关键的特性,红黑树总是用红链接将新节点和父节点相连;红连接在后面的变化中会转化为黑链接。
1.左旋
Node x = h.right; //其实就是h是父节点,x是右红连接
h.right = x.left;//可以想象成拆开x树和h树,中间值赋给左旋后的空位
x.left = h;//上下位置互换,左旋过程
x.color = h.color; x.N = h.N;
h.color = RED;//左旋
……
return x;
2.右旋
x = h.left; //h是父节点,x是左红连接
h.left = x.right;
x.right = h;//右旋过程
x.color = h.color;
h.color = RED;//右旋
……
return x;
旋转保证了有序性和平衡性;
其实理解了旋转原理是可以手撕的,但也不用记得那么准确;
3.颜色转换
h.color = RED;
h.left.color = BLACK;
h.left.color = BLACK;
put
理解了3-节点插入新键的过程,再从判断的角度的角度想,有4种情况;
最后还要递归调用,才能在每一层做旋转和颜色变换操作;
Node put(Node h, Key key, Value val){
if (cmp < 0) h.left = put(h.left);
else if (cmp > 0) h.right = put(h.right);
else h.val = val;
if(isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
if(isRed(h.right) && isRed(h.left.left)) h = rotateRight(h);
if(isRed(h.right) && isRed(h.right)) h = flipColor(h);
//红色右链接的4-节点
//红色左链接,红色左左链接,就是左连接4-节点
//红色左链接,红色右链接
//最后一种是红色右链接3-节点,一次左旋就完成了,其实就是第一种;
}
为什么用红黑树不用AVL树?
红黑树的插入删除速度更快,AVL用于自平衡的计算牺牲了插入删除性能;
红黑树为什么是平衡的,因为生长都发生在根部;
这个我是对B树的理解,B树总是push up,2-3树也是一个道理;