mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #0 - First Release
This commit is contained in:
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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 java.util.ArrayDeque;
|
||||
import java.util.BitSet;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* A variant of {@link TreeTraverser} for binary trees, providing additional
|
||||
* traversals specific to binary trees.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
* @since 15.0
|
||||
*/
|
||||
@Beta
|
||||
@GwtCompatible(emulated = true)
|
||||
public abstract class BinaryTreeTraverser<T> extends TreeTraverser<T> {
|
||||
// TODO(user): make this GWT-compatible when we've checked in ArrayDeque and
|
||||
// BitSet emulation
|
||||
|
||||
/**
|
||||
* Returns the left child of the specified node, or {@link Optional#absent()} if
|
||||
* the specified node has no left child.
|
||||
*/
|
||||
public abstract Optional<T> leftChild(T root);
|
||||
|
||||
/**
|
||||
* Returns the right child of the specified node, or {@link Optional#absent()}
|
||||
* if the specified node has no right child.
|
||||
*/
|
||||
public abstract Optional<T> rightChild(T root);
|
||||
|
||||
/**
|
||||
* Returns the children of this node, in left-to-right order.
|
||||
*/
|
||||
@Override
|
||||
public final Iterable<T> children(final T root) {
|
||||
checkNotNull(root);
|
||||
return new FluentIterable<T>() {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new AbstractIterator<T>() {
|
||||
boolean doneLeft;
|
||||
boolean doneRight;
|
||||
|
||||
@Override
|
||||
protected T computeNext() {
|
||||
if (!doneLeft) {
|
||||
doneLeft = true;
|
||||
Optional<T> left = leftChild(root);
|
||||
if (left.isPresent()) {
|
||||
return left.get();
|
||||
}
|
||||
}
|
||||
if (!doneRight) {
|
||||
doneRight = true;
|
||||
Optional<T> right = rightChild(root);
|
||||
if (right.isPresent()) {
|
||||
return right.get();
|
||||
}
|
||||
}
|
||||
return endOfData();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
UnmodifiableIterator<T> preOrderIterator(T root) {
|
||||
return new PreOrderIterator(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimized implementation of preOrderIterator for binary trees.
|
||||
*/
|
||||
private final class PreOrderIterator extends UnmodifiableIterator<T> implements PeekingIterator<T> {
|
||||
private final Deque<T> stack;
|
||||
|
||||
PreOrderIterator(T root) {
|
||||
this.stack = new ArrayDeque<T>();
|
||||
stack.addLast(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !stack.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
T result = stack.removeLast();
|
||||
pushIfPresent(stack, rightChild(result));
|
||||
pushIfPresent(stack, leftChild(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T peek() {
|
||||
return stack.getLast();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
UnmodifiableIterator<T> postOrderIterator(T root) {
|
||||
return new PostOrderIterator(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimized implementation of postOrderIterator for binary trees.
|
||||
*/
|
||||
private final class PostOrderIterator extends UnmodifiableIterator<T> {
|
||||
private final Deque<T> stack;
|
||||
private final BitSet hasExpanded;
|
||||
|
||||
PostOrderIterator(T root) {
|
||||
this.stack = new ArrayDeque<T>();
|
||||
stack.addLast(root);
|
||||
this.hasExpanded = new BitSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !stack.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
while (true) {
|
||||
T node = stack.getLast();
|
||||
boolean expandedNode = hasExpanded.get(stack.size() - 1);
|
||||
if (expandedNode) {
|
||||
stack.removeLast();
|
||||
hasExpanded.clear(stack.size());
|
||||
return node;
|
||||
} else {
|
||||
hasExpanded.set(stack.size() - 1);
|
||||
pushIfPresent(stack, rightChild(node));
|
||||
pushIfPresent(stack, leftChild(node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(user): see if any significant optimizations are possible for
|
||||
// breadthFirstIterator
|
||||
|
||||
public final FluentIterable<T> inOrderTraversal(final T root) {
|
||||
checkNotNull(root);
|
||||
return new FluentIterable<T>() {
|
||||
@Override
|
||||
public UnmodifiableIterator<T> iterator() {
|
||||
return new InOrderIterator(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final class InOrderIterator extends AbstractIterator<T> {
|
||||
private final Deque<T> stack;
|
||||
private final BitSet hasExpandedLeft;
|
||||
|
||||
InOrderIterator(T root) {
|
||||
this.stack = new ArrayDeque<T>();
|
||||
this.hasExpandedLeft = new BitSet();
|
||||
stack.addLast(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T computeNext() {
|
||||
while (!stack.isEmpty()) {
|
||||
T node = stack.getLast();
|
||||
if (hasExpandedLeft.get(stack.size() - 1)) {
|
||||
stack.removeLast();
|
||||
hasExpandedLeft.clear(stack.size());
|
||||
pushIfPresent(stack, rightChild(node));
|
||||
return node;
|
||||
} else {
|
||||
hasExpandedLeft.set(stack.size() - 1);
|
||||
pushIfPresent(stack, leftChild(node));
|
||||
}
|
||||
}
|
||||
return endOfData();
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void pushIfPresent(Deque<T> stack, Optional<T> node) {
|
||||
if (node.isPresent()) {
|
||||
stack.addLast(node.get());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user