红黑树
红黑树与AVL:https://www.jianshu.com/p/37436ed14cc6
红黑树:https://www.jianshu.com/p/e136ec79235c
https://baijiahao.baidu.com/s?id=1641940303518144126&wfr=spider&for=pc
https://www.cnblogs.com/skywang12345/p/3245399.html
---
AVL树:https://www.jianshu.com/p/fa7db1bb2577
二叉搜索树:https://blog.csdn.net/rodman177/article/details/89771156
---
红黑树的笔记:https://www.yuque.com/books/share/9f4576fb-9aa9-4965-abf3-b3a36433faa6/erw9ri
ggmc。
-------------------------------
红黑树的定义:
插入的节点是默认的红色的。
先左旋后右旋。
先变色再旋转。
旋转的条件:
---
代码:
代码:root是根节点 x为插入的节点
static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
TreeNode<K,V> x) {
// 新节点默认为红色
x.red = true;
// xp表示x的父结点,xpp表示x的祖父结点,xppl表示xpp的左孩子结点,xppr表示xpp的右孩子结点
for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
// 如果x没有父结点,则表示x是第一个结点,自动为根节点,根节点为黑色
if ((xp = x.parent) == null) {
x.red = false;
return x;
}
// 如果父结点不是红色(就是黑色),或者x没有祖父节点,那么就证明x是第二层节点,父节点为根节点
// 这种情况无需就行操作
else if (!xp.red || (xpp = xp.parent) == null)
return root;
// 进入到这里,表示x的父节点为红色
// 如果x的父节点是祖父结点的左孩子
if (xp == (xppl = xpp.left)) {
// 祖父结点的右孩子,也就是x的叔叔节点不为空,且为红色
if ((xppr = xpp.right) != null && xppr.red) {
// 父节点和叔叔节点都为红色,只需要变色,且将x替换为祖父节点然后进行递归
xppr.red = false;
xp.red = false;
xpp.red = true;
x = xpp;
}
// 如果叔叔节点为空,或者为黑色
else {
// 如果x节点为xp的右孩子
if (x == xp.right) {
// 先进行左旋,并且把x替换为xp进行递归,在左旋的过程中产生了新的root节点
root = rotateLeft(root, x = xp);
// x替换后,修改xp和xpp
xpp = (xp = x.parent) == null ? null : xp.parent;
}
// 如果x本来是左孩子,或者已经经过了上面的左旋之后,进行变色加右旋
if (xp != null) {
xp.red = false;
if (xpp != null) {
xpp.red = true;
root = rotateRight(root, xpp);
}
}
}
}
// 如果x的父节点是祖父结点的右孩子
else {
if (xppl != null && xppl.red) {
xppl.red = false;
xp.red = false;
xpp.red = true;
x = xpp;
}
else {
if (x == xp.left) {
root = rotateRight(root, x = xp);
xpp = (xp = x.parent) == null ? null : xp.parent;
}
if (xp != null) {
xp.red = false;
if (xpp != null) {
xpp.red = true;
root = rotateLeft(root, xpp);
}
}
}
}
}
}
---p4---