之前我分析过avl树,今天我在继续分析特化的AVL树(红黑树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。在我们实际的用途中,用的很多;例如 TreeMap排序等等,以达到快速查找数据的效果
红黑树(RBT)的定义:它或者是一棵空树,或者是具有一下性质的平衡二叉查找树
上图根据红黑树的基本性质,做了一个基本的红黑树展示
对平衡树的一种改进,任意一个节点,它的红黑树的间隔不超过一倍,但它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。
二叉排序树学习构建方式及如何遍历二叉排序树
插入节点过后就有可能导致用红黑树颜色不正确,因此我们需要重新维持树型
插入节点的父节点是红色 ,就有下面几种情况
对策: 将当前节点的父节点和叔叔节点涂黑,祖父节点涂红,把当前节点指向祖父节点,从新的当前节点开始算法
n节点代表 当前节点 p 代表父亲节点 g 代表祖父节点 u代表叔叔节点
为什么这样去把原有节点的父亲节点涂,这也是为了保证红黑树的特性不变因此做的处理,需要将祖父节点涂红
对策: 以当前节点为支点左旋,当前节点的左节点做为新的当前节点。
对策:父节点变为黑色,祖父节点变红色,再父节点为支点进行右旋
父节点是祖父节点的右孩子,和上面情况一样,将左全部变成右即可
父亲是祖父节点的左孩子, 祖父节点的另一个子节点(叔叔节点)是红色,则 要将颜色进行变换成红黑树的性质,并不旋转
父亲是祖父节点的左孩子, 叔叔节点是黑色,当前节点是父节点的右孩子, 当前节点左旋后,将左节点设为当前节点
父亲是祖父节点的左孩子, 叔叔节点是黑色,当前节点是父节点的左孩子, 要将颜色进行变换成红黑树的性质,然后在以父节点进行右旋,就成为最后的红黑树了
父节点是祖父节点的右孩子 ;和上面情况一样,将左全部变成右即可
整个红黑树维持红黑节点的平衡,相对于avl来说,不是要求的强平衡,在我看来,有一点弱平衡的感觉;为什么在实际的数据结构运用中,运用很多,我想就是不用特别强调平衡,既效率提升,又保持频繁插入时,数据的时间复杂度,相当于用了一些空间复杂度,来换取更高的效果
删除节点:先进行二叉排序树的删除操作,然后已替换节点作为当前节点进行后面的平衡操作
对策:把父节点染成红色,兄弟节点染成黑色,对父节点进行左旋,重新设置x的兄弟节点
对策:将x的兄弟节点设为红色,设置x的父节点为新的x节点
对策:将x兄弟节点的左孩子设为黑色,将x兄弟节点设置红色,将x的兄弟节点右旋,右旋后,重新设置x的兄弟节点。
对策:把兄弟节点染成当前节点父节点颜色,把当前节点父节点染成黑色,兄弟节点右孩子染成黑色,再以当前节点的父节点为支点进行左旋,算法结算
被删除节点是父节点的右孩子 把上面的左设置为右
被删除节点是父节点的左孩子,当前节点是根节点 保持原样
被删除节点是父节点的左孩子,当前节点x的兄弟节点是红色(此时父节点和兄弟节点的子节点分为黑) ,解决办法是:把父节点染成红色,兄弟节点染成黑色,对父节点进行左旋,重新设置x的兄弟节点
被删除节点是父节点的左孩子,当前节点x 的兄弟节点是黑色,兄弟节点的两个孩子都是黑色;解决:将x的兄弟节点设为红色,设置x的父节点为新的x节点
被删除节点是父节点的左孩子,当前节点x 的兄弟节点是黑色,兄弟的右孩子是黑色,左孩子是红色 ,解决:将x兄弟节点的左孩子设为黑色,将x兄弟节点设置红色,将x的兄弟节点右旋,右旋后,重新设置x的兄弟节点。
被删除节点是父节点的左孩子,当前节点x 的兄弟节点是黑色,兄弟的右孩子是黑色,兄弟节点的右孩子是红色 解决:把兄弟节点染成当前节点父节点颜色,把当前节点父节点染成黑色,兄弟节点右孩子染成黑色,再以当前节点的父节点为支点进行左旋,算法结算
被删除节点是父节点的右孩子 把上面的左设置为右即可
不知道各位在发现在保持红黑树的特性的平衡的时候:
具体的可以看看 我这篇分析
二叉平衡搜索树AVL 学习解析 及代码实现研究
这里遍历树,还是采用分治法,或者前序,中序遍历,后续遍历,这里我说一下中序遍历
public void midOrderTraverse(TreeNode root){
if(root==null){
return;
}
//LDR
midOrderTraverse(root.leftChild);
System.out.print(root.data+" ");
midOrderTraverse(root.rightChild);
}
对于二叉排序树来说,用中序来遍历是能做顺序遍历,利用递归的方式进行实现中序遍历 实现代码量是最少的,
利用 先遍历左边知道为空时,才返回打印最左边节点,在查看最左边节点右孩子肯定不存,就往上走,打印数据,在往右孩子走;以此类推,利用递归的特性
整个红黑树的原理,保证二叉排序树;其次主要就是围绕着保证红黑树特性,保证它的特性;降低查询数据的时间复杂度,在代码中还是应用很多的;这篇数据结构我没有代码的实现分析,我放到了treemap里面分析;大家有兴趣可以关注我分析的treemap集合