11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * express or implied. See the License for the specific language governing permissions and 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstSide.LEFT; 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstSide.RIGHT; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tools to perform single-key queries and mutations in binary search trees. 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertfinal class BstOperations { 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private BstOperations() {} 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the node with key {@code key} in {@code tree}, if any. 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> N seek( 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Comparator<? super K> comparator, @Nullable N tree, @Nullable K key) { 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(comparator); 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (tree == null) { 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int cmp = comparator.compare(key, tree.getKey()); 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (cmp == 0) { 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return tree; 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstSide side = (cmp < 0) ? LEFT : RIGHT; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return seek(comparator, tree.childOrNull(side), key); 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the result of performing the mutation specified by {@code mutationRule} in {@code 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * tree} at the location with key {@code key}. 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>If the returned {@link BstModificationResult} has type {@code IDENTITY}, the exact 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * original tree is returned. 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>If the returned {@code BstModificationResult} has type {@code REBUILDING_CHANGE}, 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the tree will be rebuilt with the node factory of the mutation rule, but not rebalanced. 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>If the returned {@code BstModificationResult} has type {@code REBALANCING_CHANGE}, 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the tree will be rebalanced using the balance policy of the mutation rule. 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> mutate( 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Comparator<? super K> comparator, BstMutationRule<K, N> mutationRule, @Nullable N tree, 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable K key) { 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(comparator); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(mutationRule); 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (tree != null) { 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int cmp = comparator.compare(key, tree.getKey()); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (cmp != 0) { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstSide side = (cmp < 0) ? LEFT : RIGHT; 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> mutation = 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert mutate(comparator, mutationRule, tree.childOrNull(side), key); 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return mutation.lift( 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tree, side, mutationRule.getNodeFactory(), mutationRule.getBalancePolicy()); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return modify(tree, key, mutationRule); 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Perform the local mutation at the tip of the specified path. 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> mutate( 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstInOrderPath<N> path, BstMutationRule<K, N> mutationRule) { 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(path); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(mutationRule); 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstBalancePolicy<N> balancePolicy = mutationRule.getBalancePolicy(); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory = mutationRule.getNodeFactory(); 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstModifier<K, N> modifier = mutationRule.getModifier(); 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N target = path.getTip(); 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key = target.getKey(); 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> result = modify(target, key, mutationRule); 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (path.hasPrefix()) { 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstInOrderPath<N> prefix = path.getPrefix(); 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result = result.lift(prefix.getTip(), path.getSideOfExtension(), nodeFactory, balancePolicy); 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert path = prefix; 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Perform the local mutation right here, at the specified node. 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, N extends BstNode<K, N>> BstMutationResult<K, N> modify( 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable N tree, K key, BstMutationRule<K, N> mutationRule) { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstBalancePolicy<N> rebalancePolicy = mutationRule.getBalancePolicy(); 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory = mutationRule.getNodeFactory(); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstModifier<K, N> modifier = mutationRule.getModifier(); 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N originalRoot = tree; 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N changedRoot; 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N originalTarget = (tree == null) ? null : nodeFactory.createLeaf(tree); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstModificationResult<N> modResult = modifier.modify(key, originalTarget); 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N originalLeft = null; 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N originalRight = null; 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (tree != null) { 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert originalLeft = tree.childOrNull(LEFT); 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert originalRight = tree.childOrNull(RIGHT); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (modResult.getType()) { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case IDENTITY: 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = tree; 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert break; 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case REBUILDING_CHANGE: 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (modResult.getChangedTarget() != null) { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory.createNode(modResult.getChangedTarget(), originalLeft, originalRight); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (tree == null) { 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = null; 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError( 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "Modification result is a REBUILDING_CHANGE, but rebalancing required"); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert break; 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case REBALANCING_CHANGE: 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (modResult.getChangedTarget() != null) { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = rebalancePolicy.balance( 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory, modResult.getChangedTarget(), originalLeft, originalRight); 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (tree != null) { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = rebalancePolicy.combine(nodeFactory, originalLeft, originalRight); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert changedRoot = null; 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert break; 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BstMutationResult.mutationResult(key, originalRoot, changedRoot, modResult); 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the result of removing the minimum element from the specified subtree. 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> extractMin( 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N root, BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) { 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(root); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(nodeFactory); 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(balancePolicy); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (root.hasChild(LEFT)) { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> subResult = 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extractMin(root.getChild(LEFT), nodeFactory, balancePolicy); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return subResult.lift(root, LEFT, nodeFactory, balancePolicy); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BstMutationResult.mutationResult( 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert root.getKey(), root, root.childOrNull(RIGHT), 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstModificationResult.rebalancingChange(root, null)); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the result of removing the maximum element from the specified subtree. 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> extractMax( 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N root, BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) { 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(root); 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(nodeFactory); 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(balancePolicy); 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (root.hasChild(RIGHT)) { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> subResult = 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extractMax(root.getChild(RIGHT), nodeFactory, balancePolicy); 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return subResult.lift(root, RIGHT, nodeFactory, balancePolicy); 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BstMutationResult.mutationResult(root.getKey(), root, root.childOrNull(LEFT), 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstModificationResult.rebalancingChange(root, null)); 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Inserts the specified entry into the tree as the minimum entry. Assumes that {@code 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry.getKey()} is less than the key of all nodes in the subtree {@code root}. 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <N extends BstNode<?, N>> N insertMin(@Nullable N root, N entry, 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) { 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(nodeFactory); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(balancePolicy); 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (root == null) { 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createLeaf(entry); 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return balancePolicy.balance(nodeFactory, root, 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert insertMin(root.childOrNull(LEFT), entry, nodeFactory, balancePolicy), 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert root.childOrNull(RIGHT)); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Inserts the specified entry into the tree as the maximum entry. Assumes that {@code 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry.getKey()} is greater than the key of all nodes in the subtree {@code root}. 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <N extends BstNode<?, N>> N insertMax(@Nullable N root, N entry, 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) { 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(entry); 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(nodeFactory); 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(balancePolicy); 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (root == null) { 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createLeaf(entry); 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return balancePolicy.balance(nodeFactory, root, root.childOrNull(LEFT), 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert insertMax(root.childOrNull(RIGHT), entry, nodeFactory, balancePolicy)); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 229