1. 简介
红黑树是一种自平衡二叉查找树,在查找,插入和删除几个方面,性能都可以做到O(lgN)。
那怎么实现呢,首先要先看看红黑树的5个特性,只有满足这5个特性,才是红黑树。
每个结点都有父结点(parent),左子结点(left)和右子结点(right), root的父结点是leaf结点。
下图便是一个简单的红黑树,
60为根结点,60的左子结点为30,60的右子结点为80,60的父结点为leaf结点;
30的父结点为60,30的左子结点和右子结点为leaf结点;
80的父结点为60,80的左子结点和右子结点为leaf结点;
为了简洁,后续图片将不显示leaf结点和left,right和parent关系描述。
2.旋转
在插入和删除元素的时候,都会用到旋转,所以有必要先介绍一下。
2.1 左转
比如选定一结点60,进行左转,实际是将xl转成x.right的left,有点绕,看图和代码就清楚了。
RBNode y = x.right; x.right = y.left; if(y.left != leaf) y.left.parent = x; y.parent = x.parent; if(x.parent == leaf) root = y; else if(x.parent.left == x) x.parent.left = y; else if(x.parent.right == x) x.parent.right = y; y.left = x; x.parent = y;
这只是一个示例,左转必须要按照一定规律来转,随便转肯定会出事,在插入时将会告诉你什么时候才能转。
2.2 右转
比如选定一点结点60,进行右转:
RBNode y = x.left; x.left = y.right; if(y.right != leaf) y.right.parent = x; y.parent = x.parent; if(x.parent == leaf) root = y; else if(x.parent.left == x) x.parent.left = y; else x.parent.right = y; y.right = x; x.parent = y;
3.插入
现在,我们正式进入主题,元素插入后,如何进行调整,变成一颗合格的红黑树呢。以下我们将会用一些示例来讲解。
3.1 元素插入
在二叉树中插入{key:value.hashCode,value},该逻辑简单,略过,如不明白可看后面的源代码。
约定:
1.新插入的结点都为红色。
2. 某结点的左子结点指向leaf,可以说成左子结点不存在,或者没有左子结点
3. 某结点的左子结点指向leaf,可以说成左子结点存在,或者有左子结点
4.某结点的右子结点指向leaf,可以说成右子结点不存在,或者没有右子结点
4.某结点的右子结点指向leaf,可以说成右子结点存在,或者有右子结点
特殊场景的先决条件是:当前结点与父结点都为红色。
插入有几个特殊场景需要特别处理:
3.1.1 Case1 祖父孙 单减
转变后父结点黑色,子结点红色
3.1.2 Case2 祖父孙结点单增
转变后父结点黑色,子结点红色
3.1.3 Case3 叔结点为红色
3.1.4 Case4 当前结点为右子结点,父结点为左结点,叔结点没有或者黑色
3.1.5 Case5 当前结点为右子结点,父结点为左结点,叔结点没有或者黑色
原文地址:https://www.cnblogs.com/liufu627/p/12129791.html