All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.BstInOrderPath Maven / Gradle / Ivy

Go to download

Guava is a suite of core and expanded libraries that include utility classes, google's collections, io classes, and much much more. This project includes GWT-friendly sources.

There is a newer version: 33.2.1-jre
Show newest version
/*
 * Copyright (C) 2011 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.collect;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Optional;

import java.util.NoSuchElementException;

import javax.annotation.Nullable;

/**
 * A {@code BstPath} supporting inorder traversal operations.
 *
 * @author Louis Wasserman
 */
@GwtCompatible
final class BstInOrderPath> extends BstPath> {
  /**
   * The factory to use to construct {@code BstInOrderPath} values.
   */
  public static > BstPathFactory> inOrderFactory() {
    return new BstPathFactory>() {
      @Override
      public BstInOrderPath extension(BstInOrderPath path, BstSide side) {
        return BstInOrderPath.extension(path, side);
      }

      @Override
      public BstInOrderPath initialPath(N root) {
        return new BstInOrderPath(root, null, null);
      }
    };
  }

  private static > BstInOrderPath extension(
      BstInOrderPath path, BstSide side) {
    checkNotNull(path);
    N tip = path.getTip();
    return new BstInOrderPath(tip.getChild(side), side, path);
  }

  private final BstSide sideExtension;
  private transient Optional> prevInOrder;
  private transient Optional> nextInOrder;

  private BstInOrderPath(
      N tip, @Nullable BstSide sideExtension, @Nullable BstInOrderPath tail) {
    super(tip, tail);
    this.sideExtension = sideExtension;
    assert (sideExtension == null) == (tail == null);
  }

  private Optional> computeNextInOrder(BstSide side) {
    if (getTip().hasChild(side)) {
      BstInOrderPath path = extension(this, side);
      BstSide otherSide = side.other();
      while (path.getTip().hasChild(otherSide)) {
        path = extension(path, otherSide);
      }
      return Optional.of(path);
    } else {
      BstInOrderPath current = this;
      while (current.sideExtension == side) {
        current = current.getPrefix();
      }
      current = current.prefixOrNull();
      return Optional.fromNullable(current);
    }
  }

  private Optional> nextInOrder(BstSide side) {
    Optional> result;
    switch (side) {
      case LEFT:
        result = prevInOrder;
        return (result == null) ? prevInOrder = computeNextInOrder(side) : result;
      case RIGHT:
        result = nextInOrder;
        return (result == null) ? nextInOrder = computeNextInOrder(side) : result;
      default:
        throw new AssertionError();
    }
  }

  /**
   * Returns {@code true} if there is a next path in an in-order traversal in the given direction.
   */
  public boolean hasNext(BstSide side) {
    return nextInOrder(side).isPresent();
  }

  /**
   * Returns the next path in an in-order traversal in the given direction.
   *
   * @throws NoSuchElementException if this would be the last path in an in-order traversal
   */
  public BstInOrderPath next(BstSide side) {
    if (!hasNext(side)) {
      throw new NoSuchElementException();
    }
    return nextInOrder(side).get();
  }

  /**
   * Returns the direction this path went in relative to its tail path, or {@code null} if this
   * path has no tail.
   */
  public BstSide getSideOfExtension() {
    return sideExtension;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy