boolean delete(Object x, int parentIndex) { int i = childToInsertAt(x, true); int priorParentIndex = parentIndex; BTreeNode temp = this; if (i != -1) { do { if (temp.entries[i] == null || temp.entries[i].child == null) return false; temp = temp.entries[i].child; priorParentIndex = parentIndex; parentIndex = i; i = temp.childToInsertAt(x, true); } while (i != -1); } // Now temp contains element to delete and temp's parentIndex is parentIndex if (temp.isLeaf()) { // If leaf and have more than MIN elements, simply delete if (temp.nrElements > MIN) { temp.deleteElement(x); BTreeSet.this.size--; return true; } // else - If leaf and have less than MIN elements, than prepare the BTreeSet for deletion temp.prepareForDeletion(parentIndex); temp.deleteElement(x); BTreeSet.this.size--; temp.fixAfterDeletion(priorParentIndex); return true; } // else - Only delete at leaf so first switch with successor than delete temp.switchWithSuccessor(x); parentIndex = temp.childToInsertAt(x, false) + 1; return temp.entries[parentIndex].child.delete(x, parentIndex); }
private void fixAfterDeletion(int parentIndex) { if (isRoot() || parent.isRoot()) return; // No fixing needed if (parent.nrElements < MIN) { // If parent lost it's n/2 element repair it BTreeNode temp = parent; temp.prepareForDeletion(parentIndex); if (temp.parent == null) return; // Root changed if (!temp.parent.isRoot() && temp.parent.nrElements < MIN) { // If need be recurse BTreeNode x = temp.parent.parent; int i = 0; // Find parent's parentIndex for (; i < entries.length; i++) if (x.entries[i].child == temp.parent) break; temp.parent.fixAfterDeletion(i); } } }