// Textbook fragment 10.08 /** Returns a child of p with height no smaller than that of the other child * / protected Position<Entry<K,V>> tallerChild(Position<Entry<K,V>> p) { if (height(left(p)) > height(right(p))) return left(p); else if (height(left(p)) < height(right(p))) return right(p); // equal height children - break tie using parent's type if (isRoot(p)) return left(p); if (p == left(parent(p))) return left(p); else return right(p); } /** * Rebalance method called by insert and remove. Traverses the path from * zPos to the root. For each node encountered, we recompute its height * and perform a trinode restructuring if it's unbalanced. */ protected void rebalance(Position<Entry<K,V>> zPos) { if(isInternal(zPos)) setHeight(zPos); while (!isRoot(zPos)) { // traverse up the tree towards the root zPos = parent(zPos); setHeight(zPos); if (!isBalanced(zPos)) { // perform a trinode restructuring at zPos's tallest grandchild Position<Entry<K,V>> xPos = tallerChild(tallerChild(zPos)); zPos = restructure(xPos); // tri-node restructure (from parent class) setHeight(left(zPos)); // recompute heights setHeight(right(zPos)); setHeight(zPos); } } } // overridden methods of the dictionary ADT public Entry<K,V> insert(K k, V v) throws InvalidKeyException { Entry<K,V> toReturn = super.insert(k, v); // calls our createNode method rebalance(actionPos); // rebalance up from the insertion position return toReturn; } public Entry<K,V> remove(Entry<K,V> ent) throws InvalidEntryException { Entry<K,V> toReturn = super.remove(ent); if (toReturn != null) // we actually removed something rebalance(actionPos); // rebalance up the tree return toReturn; } } // end of AVLTree class