二叉查找树:
1.至多两个子节点;
2.左子节点小于父节点,右子节点大于父节点
平衡二叉树(AVL):
1.具有二叉树的全部特性;
2.每个节点的左子树和右子树的高度差至多等于1。
为什么有了二叉平衡树(AVL)还需要红黑树?
虽然AVL解决了二叉查找树退化为近似链表的缺点,能够把查找时间控制在O(logn),不过却不是最佳的。
因为平衡树要求每个节点的左子树和右子树的高度差至多为1,这个要求太严格了,导致每次进行插入/删除节点的时候,
几乎都会破坏平衡树的第二个规则,进而我们都需要通过左旋和右旋来进行调整,使之再次成为一颗符合要求的平衡树
红黑树的性质:
1.每个节点要么是黑色,要么是红色
2.根节点是黑色
3.每个叶子节点(nil)是黑色
4.每个红色节点的两个子节点一定是黑色,不能有两个红色节点相连
5.任意一节点到每个叶子结点的路径都包含数量相等的。俗称黑高黑节点
5.1 如果一个节点存在黑色子节点,那么该节点肯定有两个子节点
黑色完美平衡
变色:节点的颜色由红变黑或由黑变红
左旋:
上升的节点有两个左分支,剪断一个原来的左分支,补到下沉节点的右分支上
右旋
上升的节点有两个右分支,剪断一个原来的右分支,补到下沉节点的左分支上
红黑树插入节点场景分析
插入节点必须为红色,如果是黑色则必打破平衡,红色就不一定了
1. 红黑树为空树
直接插入即可,要为黑色
2. 插入节点的key已存在
更新当前节点的值,为插入节点的值
3.插入节点的父节点为黑节点
由于插入的节点是红色的,当插入黑色的节点时并不会影响红黑树的平衡,直接插入即可。
4.插入节点的父节点为红色
回想下红黑树的性质2:根节点是黑色。如果插入节点的父节点为红节点。那么该父节点不可能为根节点,所以插入节点总是存在祖父节点
这样会造成黑红红
4.1 叔叔节点存在并且为红节点
依据红黑树性质4可知,红色节点不能相连—>祖父节点肯定为黑节点。
因为不可以同时存在两个相连的红节点,那么此时插入子树的红黑层数的情况是:黑红红,最简单的处理方式就是把其改为:红黑红
处理:
- 将P和U节点改为黑色
- 将PP改为红色
- 将PP设置为当前节点,进行后续处理
可以看到,我们把PP节点设置为红色了,如果PP的父节点为黑色,那么无需再做任何处理;
4.2 叔叔节点不存在或为黑节点,并且插入节点的父节点是祖父节点的左子节点
注意:单纯从插入前来看,叔叔节点非红即空(NIL节点),否则的话破坏了红黑树性质5,此路径会比其他路径多一个黑色节点
4.2.1 新插入节点,为其父节点的左子节点(LL红色情况)
处理:
1.变色:将P设置为黑色,将PP设置为红色
2.对PP节点进行右旋(此时如果PP的父节点为黑色,则不用进行右旋操作)
4.2.2 新插入节点,为其父节点的右子节点(LR红色情况)
处理:
- 对P进行左旋
- 将P设置为当前接节点,得到LL红色情况
- 按照LL红色情况处理(1变颜色2右旋PP)
4.3 叔叔节点不存在或为黑节点,并且插入节点的父节点时祖父节点的右子节点
4.3.1 新插入节点,为其父节点的右子节点(RR红色情况)
处理:
1.变色:将P设置为黑色,将pp设置为红色
2.对PP节点左旋
4.3.2 新插入节点,为其父节点的左子节点(RL红色情况)
处理:
- 对P进行右旋
- 将P设置为当前节点,得到RR红色情况
- 按照RR红色情况处理(1变色2左旋PP)