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