4.1 元素删除
约定:
删除一个结点z,如果有该结点有子结点,需要查找该结点的左树最大值y来替换,同时又需要用叶结点x来替换y的位置。
在二叉树中删除一个结点有以下几种情况,以删除红结点为例,删除黑结点也差不多,最重要的多必须检查代替的结点是不是子结点,是不是黑结点。
Tip: 算法导论中谈到找右树最小值,我这里以左树最大值来代替删除结点,只是left和right的替换而已,原理都是一样。可以参照 红黑树可视化网站,https://www.cs.usfca.edu/~galles/visualization/RedBlack.html 我也受益很多。
以后有空的时候再组织语言,感谢
附上代码方便参阅。
package alf.collection; /** * Red -Black tree struct, make values‘ hash as key * @param <V> */ public class SimpleRBTree<V> { public SimpleRBTree() { leaf = new SimpleRBNode<>(Integer.MIN_VALUE, null, null); leaf.color = RBColor.BLACK; leaf.left = leaf.right = leaf; root = leaf; } public void Insert(V... values) { for (V item : values) { Insert(item); } } public void Insert(V value) { int key = value.hashCode(); SimpleRBNode<V> node = new SimpleRBNode<V>(key, value, leaf); SimpleRBNode y = leaf; SimpleRBNode<V> x = root; while (x != leaf) { y = x; if (key < x.key) x = x.left; else if (key > x.key) x = x.right; else break; } if (root == y ) { if (root == leaf ) { root = node; root.color = RBColor.BLACK; return; } else if (root.key == key) { root.value = value; return; } } if(y.key == key) { y.value = value; return; } node = new SimpleRBNode<V>(key, value, leaf); node.parent = y; if (key < y.key) { y.left = node; } else if (key > y.key) { y.right = node; } else { node.parent = y.parent; node.left = y.left; node.right = y.right; if (y.parent != leaf) { if (y.parent.left == y) y.parent.left = node; else if (y.parent.right == y) y.parent.right = node; } } InsertFixUp(node); } /** * condition: both current node and parent node are RED * Case1: currentnode =grandpa node->left->left; make grandpa RED,mak parent node Black . RotateRight with parent node, z = z.parent.parent; * case2: currentnode =grandpa node->right->right; make grandpa RED,mak parent node Black . RotateLeft with parent node, z = z.parent.parent; * case3:parent and uncle node are RED, then set grandpa node RED; parent and uncle node BLACK. z=z.parent * case4: currentnode =grandpa node->left->right; RotateLeft with parent node,goto case 1 * case5: currentnode =grandpa node->right->left; RotateRight with parent node,goto case 2 * * @param z */ private void InsertFixUp(SimpleRBNode<V> z) { SimpleRBNode y = leaf; while (z.color == RBColor.RED && z.parent.color == RBColor.RED) { if (z.parent == z.parent.parent.left) { y = z.parent.parent.right; if (y != leaf && y.color == RBColor.RED) { //case 3 z.parent.color = RBColor.BLACK; y.color = RBColor.BLACK; z.parent.parent.color = RBColor.RED; z = z.parent.parent; } else if (z == z.parent.right) { //case 5 // way1: // z=z.parent; // RotateLeft(z); // z.parent.color = RBColor.BLACK; // z.parent.parent.color = RBColor.RED; // RotateRight(z.parent.parent); //way2, RotateLeft and goto case3 z = z.parent; RotateLeft(z); } else {//left-left //case 1 z.parent.color = RBColor.BLACK; z.parent.parent.color = RBColor.RED; RotateRight(z.parent.parent); z = z.parent; } } else if (z.parent == z.parent.parent.right) { y = z.parent.parent.left; if (y != leaf && y.color == RBColor.RED) { //case 3 z.parent.color = RBColor.BLACK; y.color = RBColor.BLACK; z.parent.parent.color = RBColor.RED; z = z.parent.parent; } else if (z == z.parent.left) { //case5 //way1: // z=z.parent; // RotateRight(z); // z.parent.color = RBColor.BLACK; // z.parent.parent.color = RBColor.RED; // RotateLeft(z.parent.parent); //way2:z=z.parent,Rotate current node Right and goto case 2 z = z.parent; RotateRight(z); } else { //case 2 z.parent.color = RBColor.BLACK; z.parent.parent.color = RBColor.RED; RotateLeft(z.parent.parent); z = z.parent; } } } root.color = RBColor.BLACK; } public SimpleRBNode<V> Get(int key) { SimpleRBNode x = root; boolean inFlag = false; while (x != leaf) { inFlag = true; if (key == x.key ) { break; } else if (key < x.key) x = x.left; else x = x.right; } return x; } public void Delete(V value) { SimpleRBNode x = Get(value.hashCode()); if (x != leaf) Delete(x); } public void Delete(SimpleRBNode z) { SimpleRBNode x = leaf; SimpleRBNode y = z; RBColor y_original_Color = y.color; if (z.left == leaf) { x = z.right; RBTran(z, z.right); } else if (z.right == leaf) { x = z.left; RBTran(z, z.left); } else { y = TreeMax(z.left); y_original_Color = y.color; x = y.left; if (y.parent == z) x.parent = y; else { RBTran(y, y.left); y.left = z.left; y.left.parent = y; } RBTran(z, y); y.right = z.right; y.right.parent = y; y.color = z.color; } if (y_original_Color == RBColor.BLACK) DeleteFixUp(x); z.parent = leaf; z.left = leaf; z.right = leaf; } private void DeleteFixUp(SimpleRBNode x) { SimpleRBNode w = leaf; while (x != root && x.color == RBColor.BLACK) { if (x == x.parent.left) { w = x.parent.right; if (w.color == RBColor.RED) { w.color = RBColor.BLACK; x.parent.color = RBColor.RED; RotateLeft(x.parent); w = x.parent.right; //System.out.printf("\nleft:case1\n"); } if (w.left.color == RBColor.BLACK && w.right.color == RBColor.BLACK) { w.color = RBColor.RED; x = x.parent; //System.out.printf("\nleft:case2\n"); } else if (w.right.color == RBColor.BLACK) { w.left.color = RBColor.BLACK; w.color = RBColor.RED; RotateRight(w); w = x.parent.right; System.out.printf("\nleft:case3\n"); } else { w.color = w.parent.color; x.parent.color = RBColor.BLACK; w.right.color = RBColor.BLACK; RotateLeft(x.parent); x = root; //System.out.printf("\nleft:case4\n"); } } else {//x==x.parent.right w = x.parent.left; if (w.color == RBColor.RED) { w.color = RBColor.BLACK; x.parent.color = RBColor.RED; RotateRight((x.parent)); w = x.parent.left; //System.out.printf("\nright:case1\n"); } if (w.right.color == RBColor.BLACK && w.left.color == RBColor.BLACK) { w.color = RBColor.RED; x = x.parent; //System.out.printf("\nright:case2\n"); } else if (w.left.color == RBColor.BLACK) { w.right.color = RBColor.BLACK; w.color = RBColor.RED; RotateLeft(w); w = x.parent.left; System.out.printf("\nright:case3\n"); } else { w.color = w.parent.color; x.parent.color = RBColor.BLACK; w.left.color = RBColor.BLACK; RotateRight(x.parent); x = root; //System.out.printf("\nright:case4\n"); } } } if (x.color != RBColor.BLACK) {//System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); x.color = RBColor.BLACK; } leaf.color = RBColor.BLACK; } private SimpleRBNode TreeMax(SimpleRBNode node) { SimpleRBNode x = node; SimpleRBNode y = leaf; while (x != leaf) { y = x; x = x.right; } if (y != leaf) return y; return node; } private SimpleRBNode TreeMin(SimpleRBNode node) { SimpleRBNode x = node; SimpleRBNode y = leaf; while (x != leaf) { y = x; x = x.left; } if (y != leaf) return y; return node; } private void RBTran(SimpleRBNode u, SimpleRBNode v) { if (u.parent == leaf) root = v; else if (u == u.parent.left) u.parent.left = v; else if (u == u.parent.right) u.parent.right = v; v.parent = u.parent; } private void RotateLeft(SimpleRBNode<V> x) { SimpleRBNode 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; } private void RotateRight(SimpleRBNode<V> x) { SimpleRBNode 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; } public void Print() { Print(root); } private void Print(SimpleRBNode node) { String dir = "\nroot"; if (node.parent != leaf) { if (node.parent.left == node) dir = "left"; else dir = "right"; } System.out.printf("%s:%d,%s,%s\n", dir, node.key, node.value, node.color); if (node.left != leaf) Print(node.left); if (node.right != leaf) Print(node.right); } public enum RBColor { RED(0), BLACK(1); private int value; private RBColor(int value) { this.value = value; } } public class SimpleRBNode<V> implements Comparable { private SimpleRBNode<V> left; private SimpleRBNode<V> right; private SimpleRBNode<V> parent; private int key; private V value; private RBColor color; public SimpleRBNode(int key, V value, SimpleRBNode<V> defaultLinkNode) { this.key = key; this.value = value; this.left = defaultLinkNode; this.right = defaultLinkNode; this.parent = defaultLinkNode; this.color = RBColor.RED; } @Override public int hashCode() { return key; } @Override public String toString() { return Integer.toString(key); } @Override public int compareTo(Object o) { return this.key - o.hashCode(); } } final SimpleRBNode<V> leaf; private SimpleRBNode<V> root; }
原文地址:https://www.cnblogs.com/liufu627/p/12142870.html
时间: 2024-11-13 08:14:15