标签:png editable 平衡 edit 数据 div else 四种 nod
首先的疑问,已经有了二叉平衡树,为什么又有红黑树?(前提是要理解平衡树)
引用知乎上的回答
作者:Acjx
链接:http://www.zhihu.com/question/20545708/answer/58717264
所以要明白,原由:红黑数不是严格的平衡树。红色节点是用来标记:以该节点为根节点的子树的高度要高于以该节点的兄弟节点为根节点的子树。
前提条件:
规则1:红黑树从根节点到每个叶节点的每一条路径上的黑色节点数相等;
规则2:如果一个节点是红色,它的父节点一定是黑色(也就是红色与红色之间是至少隔了一层的)。
因此,put操作,图片转载来自http://www.cnblogs.com/CarpenterLee/p/5503882.html
插入新节点固定为红色,因为不会改变路径上黑色节点的数目,即不违法规则1。这时需要看父节点,如果父节点为黑色,则不需要做任何额外操作。如果父节点为红色,违反规则2,需要看叔节点(父亲的兄弟节点)的颜色,图为父节点在祖父节点的左侧,分为两种情况:a)如果叔节点为红色,如图情况一;b)叔节点为黑色,x节点在父节点的右侧,如图情况二;c))叔节点为黑色,x节点在父节点的左侧,如图情况三。另外的三种情况是对称的,即,父节点在祖父节点的右侧。
需要注意,代码中合并了b,c两种情况,如果没有b情况,直接执行c情况,如果有b情况,先b,后c。
//红黑树调整函数fixAfterInsertion() private void fixAfterInsertion(Entry<K,V> x) {/ x.color = RED; while (x != null && x != root && x.parent.color == RED) {//注意while循环条件,和循环后的语句 if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { Entry<K,V> y = rightOf(parentOf(parentOf(x))); if (colorOf(y) == RED) {//如果y为null,则视为BLACK setColor(parentOf(x), BLACK); // 情况1 setColor(y, BLACK); // 情况1 setColor(parentOf(parentOf(x)), RED); // 情况1 x = parentOf(parentOf(x)); // 情况1 } else { if (x == rightOf(parentOf(x))) { x = parentOf(x); // 情况2,叔节点为黑色,x节点在父节点的右侧,其实就是LR旋转,还是直接进入情况3,就RR旋转 rotateLeft(x); // 情况2 } setColor(parentOf(x), BLACK); // 情况3,叔节点为黑色,x节点在父节点的左侧, RR旋转 setColor(parentOf(parentOf(x)), RED); // 情况3 rotateRight(parentOf(parentOf(x))); // 情况3 } } else { Entry<K,V> y = leftOf(parentOf(parentOf(x))); if (colorOf(y) == RED) { setColor(parentOf(x), BLACK); // 情况4 setColor(y, BLACK); // 情况4 setColor(parentOf(parentOf(x)), RED); // 情况4 x = parentOf(parentOf(x)); // 情况4 } else { if (x == leftOf(parentOf(x))) { x = parentOf(x); // 情况5 rotateRight(x); // 情况5 } setColor(parentOf(x), BLACK); // 情况6 setColor(parentOf(parentOf(x)), RED); // 情况6 rotateLeft(parentOf(parentOf(x))); // 情况6 } } } root.color = BLACK; }
删除节点,参考http://www.cnblogs.com/CarpenterLee/p/5525688.html
如果P节点至少有一个孩子节点,寻找后继节点,用后继节点替换当前结点,调整后继节点。
如果P节点没有孩子节点,直接调整p节点。
如果删除的是红色节点,不需要任何操作,
如果删除的黑色节点,
如图:
private void fixAfterDeletion(Entry<K,V> x) {//注意while循环条件,和循环后的语句 while (x != root && colorOf(x) == BLACK) { if (x == leftOf(parentOf(x))) { Entry<K,V> sib = rightOf(parentOf(x)); if (colorOf(sib) == RED) {//步骤一 setColor(sib, BLACK); // 情况1,被删除的节点p,的原兄弟节点sib为红色, setColor(parentOf(x), RED); // 情况1 rotateLeft(parentOf(x)); // 情况1 sib = rightOf(parentOf(x)); // 注意此时, } if (colorOf(leftOf(sib)) == BLACK && //步骤二,分两种,sib节点的孩子节点全部为黑色 colorOf(rightOf(sib)) == BLACK) { setColor(sib, RED); // 情况2 x = parentOf(x); // 情况2 } else { //sib的孩子节点有一个是红色,看红色是在左边则,RL旋转,如果右边,则进入情况四,直接LL旋转 if (colorOf(rightOf(sib)) == BLACK) { setColor(leftOf(sib), BLACK); // 情况3 setColor(sib, RED); // 情况3 rotateRight(sib); // 情况3 sib = rightOf(parentOf(x)); // 情况3 } setColor(sib, colorOf(parentOf(x))); // 情况4,直接LL旋转 setColor(parentOf(x), BLACK); // 情况4 setColor(rightOf(sib), BLACK); // 情况4 rotateLeft(parentOf(x)); // 情况4 x = root; // 情况4 } } else { // 跟前四种情况对称 Entry<K,V> sib = leftOf(parentOf(x)); if (colorOf(sib) == RED) { setColor(sib, BLACK); // 情况5 setColor(parentOf(x), RED); // 情况5 rotateRight(parentOf(x)); // 情况5 sib = leftOf(parentOf(x)); // 情况5 } if (colorOf(rightOf(sib)) == BLACK && colorOf(leftOf(sib)) == BLACK) { setColor(sib, RED); // 情况6 x = parentOf(x); // 情况6 } else { if (colorOf(leftOf(sib)) == BLACK) { setColor(rightOf(sib), BLACK); // 情况7 setColor(sib, RED); // 情况7 rotateLeft(sib); // 情况7 sib = leftOf(parentOf(x)); // 情况7 } setColor(sib, colorOf(parentOf(x))); // 情况8 setColor(parentOf(x), BLACK); // 情况8 setColor(leftOf(sib), BLACK); // 情况8 rotateRight(parentOf(x)); // 情况8 x = root; // 情况8 } } } setColor(x, BLACK); }
标签:png editable 平衡 edit 数据 div else 四种 nod
原文地址:http://www.cnblogs.com/nazhizq/p/6833289.html