I would prefer the AVL tree for this saturation.
here is the code you want
class BSTree { public static final int INSERT = 1; public static final int DELETE = -1; BTNode root; boolean AVL; boolean SPL; boolean RBL; BTNode lastnode; int nextside; public BSTree(int mode) { this.root = null; setMode(mode, true); } public void setMode(int mode, boolean state) { switch (mode) { case 1: if (state == true) { this.AVL = true; this.SPL = false; this.RBL = false; return; } this.AVL = false; break; case 2: if (state == true) { this.SPL = true; this.AVL = false; this.RBL = false; return; } this.SPL = false; break; case 3: if (state == true) { this.RBL = true; this.AVL = false; this.SPL = false; return; } this.RBL = false; break; default: this.AVL = false; this.SPL = false; this.RBL = false; } } public boolean isAVL() { return this.AVL; } public boolean isSPL() { return this.SPL; } public boolean isRBL() { return this.RBL; } public BTNode getRoot() { return this.root; } public void setRoot(BTNode node) { this.root = node; } public boolean isEmpty() { return (this.root == null); } public int getDepth() { int maxdepth = 0; for (BTNode node = this.root; node != null; node = node.nextPrO()) { int depth = node.getDepth(this.root); if (depth > maxdepth) maxdepth = depth; } return maxdepth; } public void destroy(BTNode node) { node = null; } public BTNode find(BTData data) { BTNode node = locate(data); if (isSPL()) splay(this.lastnode); return node; } public BTNode insert(BTData data) { if (isSPL()) { return insertSPL(data); } if (isAVL()) { return insertAVL(data); } if (isRBL()) { return insertRBL(data); } return insertBST(data); } public BTNode delete(BTData data, int minmax) { if (isAVL()) { return deleteAVL(data, minmax); } if (isSPL()) { return deleteSPL(data, minmax); } if (isRBL()) { return deleteRBL(data, minmax); } return deleteBST(data, minmax); } public BTNode locate(BTData data) { BTNode node = this.root; BTNode next = null; int side = 0; while (node != null) { side = node.compareSide(data); next = node.getChild(side); if (next == node) break; if (next == null) break; node = next; } this.lastnode = node; this.nextside = side; return next; } public BTNode add(BTNode node, int side, BTData data) { BTNode newnode = new BTNode(data); link(node, side, newnode); return newnode; } public BTNode remove(BTNode node) { BTNode child = node.getChild(); BTNode parent = node.getParent(); int side = node.getSide(); link(parent, side, child); destroy(node); return parent; } public void link(BTNode parent, int side, BTNode child) { if (child != null) child.setParent(parent); if (parent != null) parent.setChild(side, child); else this.root = child; } public BTNode rotate(BTNode node, int side) { BTNode parent = node.getParent(); BTNode child = node.getChild(-side); BTNode grand = child.getChild(side); link(node, -side, grand); link(parent, node.getSide(), child); link(child, side, node); return child; } public BTNode swap(BTNode node, int minmax) { BTNode swap = getSuccessor(node, minmax); BTNode temp = node; swapData(node, swap); node = swap; swap = temp; return node; } public BTNode getSuccessor(BTNode node, int minmax) { return ((minmax == 1) ? node.prevInO() : node.nextInO()); } public void swapData(BTNode node1, BTNode node2) { BTData data = node1.getData(); node1.setData(node2.getData()); node2.setData(data); } public void deleteAll() { for (BTNode node = this.root.firstPoO(); node != null; ) { BTNode leaf = node; node = leaf.nextPoO(); destroy(leaf); } this.root = null; } public BTNode locateBST(BTData data) { for (BTNode node = this.root; node != null; ) { int side = node.compareSide(data); if (side == 0) break; node = node.getChild(side); } return node; } public BTNode insertBST(BTData data) { if (this.root == null) return add(null, 0, data); BTNode node = locate(data); return ((node != null) ? null : add(this.lastnode, this.nextside, data)); } public BTNode deleteBST(BTData data, int minmax) { BTNode node = locate(data); if (node == null) return null; if (node.hasTwoChildren()) node = swap(node, minmax); return remove(node); } public BTNode insertAVL(BTData data) { if (this.root == null) return add(null, 0, data); if (locate(data) != null) return null; BTNode node = add(this.lastnode, this.nextside, data); rebalanceAVL(this.lastnode, this.nextside, 1); return node; } public BTNode deleteAVL(BTData data, int minmax) { BTNode node = locate(data); if (node == null) { return null; } if (node.hasTwoChildren()) { node = swap(node, minmax); } int side = node.getSide(); node = remove(node); rebalanceAVL(node, side, -1); return node; } public void rebalanceAVL(BTNode node, int side, int in) { for (; node != null; node = node.getParent()) { if (node.getBalance() != in * side) node.setBalance(node.getBalance() + in * side); else { node = rotateAVL(node); } if ((in == 1) && (node.getBalance() == 0)) return; if ((in == -1) && (node.getBalance() != 0)) return; side = node.getSide(); } } public BTNode rotateAVL(BTNode node) { int side = node.getBalance(); BTNode child = node.getChild(side); if (child.getBalance() == -side) { BTNode grand = child.getChild(-side); if (grand.getBalance() == -side) { grand.setBalance(0); child.setBalance(side); node.setBalance(0); } else if (grand.getBalance() == side) { grand.setBalance(0); child.setBalance(0); node.setBalance(-side); } else { node.setBalance(0); child.setBalance(0); } rotate(child, side); } else if (child.getBalance() == side) { node.setBalance(0); child.setBalance(0); } else if (child.getBalance() == 0) { node.setBalance(side); child.setBalance(-side); } node = rotate(node, -side); return node; } public void balanceAVL(BTNode node) { int side = node.getBalance(); BTNode child = node.getChild(side); if (child.getBalance() == -side) { BTNode grand = child.getChild(-side); if (grand.getBalance() == -side) { grand.setBalance(0); child.setBalance(side); node.setBalance(0); } else if (grand.getBalance() == side) { grand.setBalance(0); child.setBalance(0); node.setBalance(-side); } else { node.setBalance(0); child.setBalance(0); } } else if (child.getBalance() == side) { child.setBalance(0); node.setBalance(0); } else { if (child.getBalance() != 0) return; child.setBalance(-side); } } public boolean isAVLcompliant(BTNode node) { boolean balanced = true; if (node == null) return true; int l = getHeight(node.getChild(-1), 0); int r = getHeight(node.getChild(1), 0); node.setBalance(r - l); if ((r - l > 1) || (r - l < -1)) balanced = false; return ((balanced) && (isAVLcompliant(node.getChild(-1))) && (isAVLcompliant (node.getChild(1)))); } public int getHeight(BTNode node, int depth) { if (node == null) return 0; if (node.isLeaf()) { return (depth + 1); } int lmax = getHeight(node.getChild(-1), depth + 1); int rmax = getHeight(node.getChild(1), depth + 1); return ((lmax > rmax) ? lmax : rmax); } public BTNode insertSPL(BTData data) { if (this.root == null) return add(null, 0, data); BTNode node = locate(data); splay(this.lastnode); return ((node != null) ? null : splitinsert(data)); } public BTNode splitinsert(BTData data) { BTNode node = new BTNode(data); int side = -this.root.compareSide(data); BTNode child = this.root.getChild(-side); this.root.setChild(-side, null); link(node, side, this.root); link(node, -side, child); this.root = node; return this.root; } public BTNode deleteSPL(BTData data, int minmax) { BTNode node = locate(data); splay(this.lastnode); if (node == null) return null; BTNode root = node; node = getSuccessor(root, minmax); if (node != null) splay(node); return remove(root); } public void splay(BTNode node) { while (node != this.root) { BTNode parent = node.getParent(); BTNode grandparent = parent.getParent(); int side = node.getSide(); if (grandparent == null) { rotate(parent, -side); } else if (parent.getSide() == side) { rotate(grandparent, -side); rotate(parent, -side); } else { if (parent.getSide() == side) continue; rotate(parent, -side); rotate(grandparent, side); } } } public boolean isSPLcompliant() { return true; } public BTNode insertRBL(BTData data) { if (this.root == null) { this.root = add(null, 0, data); this.root.setColor(2); return this.root; } if (locate(data) != null) return null; BTNode node = add(this.lastnode, this.nextside, data); node.setColor(1); fixRBinsert(node); return node; } public void fixRBinsert(BTNode node) { while (node != this.root) { BTNode parent = node.getParent(); if (parent.getColor() == 2) break; BTNode grandparent = parent.getParent(); int side = parent.getSide(); BTNode uncle = grandparent.getChild(-side); if ((uncle != null) && (uncle.getColor() == 1)) { parent.setColor(2); uncle.setColor(2); grandparent.setColor(1); node = grandparent; } else if (node.getSide() == -side) { rotate(parent, side); node = parent; } else { if (node.getSide() != side) continue; parent.setColor(2); grandparent.setColor(1); rotate(grandparent, -side); } } this.root.setColor(2); } public BTNode deleteRBL(BTData data, int minmax) { BTNode node = locate(data); if (node == null) { return null; } if (node.hasTwoChildren()) { node = swap(node, minmax); } int color = node.getColor(); int side = node.getSide(); node = remove(node); if ((this.root != null) && (side == 0)) { this.root.setColor(2); } else if ((node != null) && (color == 2)) fixRBdelete(node, side); return node; } public void fixRBdelete(BTNode parent, int side) { BTNode node = parent.getChild(side); if ((node != null) && (node.getColor() == 1)) { node.setColor(2); return; } do { if (node != null) { parent = node.getParent(); side = node.getSide(); } BTNode sibling = parent.getChild(-side); BTNode nephew = sibling.getChild(side); BTNode niece = sibling.getChild(-side); if (sibling.getColor() == 1) { sibling.setColor(2); parent.setColor(1); rotate(parent, side); } else if ((isBlack(nephew)) && (isBlack(niece))) { sibling.setColor(1); node = (node == null) ? parent : node.getParent(); } else if ((isBlack(niece)) && (isRed(nephew))) { sibling.setColor(1); nephew.setColor(2); rotate(sibling, -side); } else { if (!(isRed(niece))) continue; sibling.setColor(parent.getColor()); parent.setColor(2) ; niece.setColor(2); rotate(parent, side); node = this.root; } } while ((node != this.root) && (isBlack(node))); node.setColor(2); } public boolean isRed(BTNode node) { return ((node != null) && (node.getColor() == 1)); } public boolean isBlack(BTNode node) { return ((node == null) || (node.getColor() == 2)); } public boolean isRBLcompliant(BTNode node) { return false; } }
This is a complete implementation. Good luck.