0001 /*
0002 * Java Genetic Algorithm Library (jenetics-5.2.0).
0003 * Copyright (c) 2007-2020 Franz Wilhelmstötter
0004 *
0005 * Licensed under the Apache License, Version 2.0 (the "License");
0006 * you may not use this file except in compliance with the License.
0007 * You may obtain a copy of the License at
0008 *
0009 * http://www.apache.org/licenses/LICENSE-2.0
0010 *
0011 * Unless required by applicable law or agreed to in writing, software
0012 * distributed under the License is distributed on an "AS IS" BASIS,
0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014 * See the License for the specific language governing permissions and
0015 * limitations under the License.
0016 *
0017 * Author:
0018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
0019 */
0020 package io.jenetics.ext.util;
0021
0022 import static java.lang.String.format;
0023 import static java.util.Objects.requireNonNull;
0024 import static java.util.Spliterators.spliteratorUnknownSize;
0025
0026 import java.io.Serializable;
0027 import java.util.Arrays;
0028 import java.util.Iterator;
0029 import java.util.Objects;
0030 import java.util.Optional;
0031 import java.util.function.Function;
0032 import java.util.stream.Stream;
0033 import java.util.stream.StreamSupport;
0034
0035 import io.jenetics.util.ISeq;
0036
0037 /**
0038 * General purpose tree structure. The interface only contains tree read methods.
0039 * For a mutable tree implementation have a look at the {@link TreeNode} class.
0040 *
0041 * @see TreeNode
0042 *
0043 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
0044 * @version 5.2
0045 * @since 3.9
0046 */
0047 public interface Tree<V, T extends Tree<V, T>> extends Iterable<T> {
0048
0049 /* *************************************************************************
0050 * Basic (abstract) operations. All other tree operations can be derived
0051 * from this methods.
0052 **************************************************************************/
0053
0054 /**
0055 * Return the value of the current {@code Tree} node. The value may be
0056 * {@code null}.
0057 *
0058 * @return the value of the current {@code Tree} node
0059 */
0060 default V value() {
0061 return getValue();
0062 }
0063
0064 /**
0065 * Return the value of the current {@code Tree} node. The value may be
0066 * {@code null}.
0067 *
0068 * @return the value of the current {@code Tree} node
0069 * @deprecated Use {@link #value()} instead
0070 */
0071 @Deprecated
0072 V getValue();
0073
0074 /**
0075 * Return the <em>parent</em> node of this tree node.
0076 *
0077 * @return the parent node, or {@code Optional.empty()} if this node is the
0078 * root of the tree
0079 */
0080 default Optional<T> parent() {
0081 return getParent();
0082 }
0083
0084 /**
0085 * Return the <em>parent</em> node of this tree node.
0086 *
0087 * @return the parent node, or {@code Optional.empty()} if this node is the
0088 * root of the tree
0089 * @deprecated Use {@link #parent()} instead
0090 */
0091 @Deprecated
0092 Optional<T> getParent();
0093
0094 /**
0095 * Return the child node with the given index.
0096 *
0097 * @param index the child index
0098 * @return the child node with the given index
0099 * @throws IndexOutOfBoundsException if the {@code index} is out of
0100 * bounds ({@code [0, childCount())})
0101 */
0102 T childAt(final int index);
0103
0104 /**
0105 * Return the number of children this tree node consists of.
0106 *
0107 * @return the number of children this tree node consists of
0108 */
0109 int childCount();
0110
0111
0112 /* *************************************************************************
0113 * Derived operations
0114 **************************************************************************/
0115
0116 /**
0117 * Return an iterator of the children of this {@code Tree} node.
0118 *
0119 * @return an iterator of the children of this {@code Tree} node.
0120 */
0121 default Iterator<T> childIterator() {
0122 return new TreeChildIterator<V, T>(Trees.self(this));
0123 }
0124
0125 /**
0126 * Return a forward-order stream of this node's children.
0127 *
0128 * @return a stream of children of {@code this} node
0129 */
0130 default Stream<T> childStream() {
0131 return StreamSupport
0132 .stream(spliteratorUnknownSize(childIterator(), 0), false);
0133 }
0134
0135 /**
0136 * Returns {@code true} if this node is the root of the tree.
0137 *
0138 * @return {@code true} if this node is the root of its tree, {@code false}
0139 * otherwise
0140 */
0141 default boolean isRoot() {
0142 return !parent().isPresent();
0143 }
0144
0145 /**
0146 * Returns the depth of the tree rooted at this node. The <i>depth</i> of a
0147 * tree is the longest distance from {@code this} node to a leaf. If
0148 * {@code this} node has no children, 0 is returned. This operation is much
0149 * more expensive than {@link #level()} because it must effectively traverse
0150 * the entire tree rooted at {@code this} node.
0151 *
0152 * @return the depth of the tree whose root is this node
0153 */
0154 default int depth() {
0155 final Iterator<T> it = breadthFirstIterator();
0156
0157 T last = null;
0158 while (it.hasNext()) {
0159 last = it.next();
0160 }
0161
0162 assert last != null;
0163 return last.level() - level();
0164 }
0165
0166 /**
0167 * Returns the number of levels above this node. The <i>level</i> of a tree
0168 * is the distance from the root to {@code this} node. If {@code this} node
0169 * is the root, returns 0.
0170 *
0171 * @return the number of levels above this node
0172 */
0173 default int level() {
0174 Optional<T> ancestor = Optional.of(Trees.self(this));
0175 int levels = 0;
0176 while ((ancestor = ancestor.flatMap(Tree<V, T>::parent)).isPresent()) {
0177 ++levels;
0178 }
0179
0180 return levels;
0181 }
0182
0183 /**
0184 * Returns the index of the specified child in this node's child array, or
0185 * {@code -1} if {@code this} node doesn't contain the given {@code child}.
0186 * This method performs a linear search and is O(n) where {@code n} is the
0187 * number of children.
0188 *
0189 * @param child the TreeNode to search for among this node's children
0190 * @throws NullPointerException if the given {@code child} is {@code null}
0191 * @return the index of the node in this node's child array, or {@code -1}
0192 * if the node could not be found
0193 */
0194 default int indexOf(final Tree<?, ?> child) {
0195 int index = -1;
0196 for (int i = 0, n = childCount(); i < n && index == -1; ++i) {
0197 if (childAt(i).identical(child)) {
0198 index = i;
0199 }
0200 }
0201
0202 return index;
0203 }
0204
0205 /**
0206 * Return the number of nodes of {@code this} node (sub-tree).
0207 *
0208 * @return the number of nodes of {@code this} node (sub-tree)
0209 */
0210 default int size() {
0211 return Trees.countChildren(this) + 1;
0212 }
0213
0214
0215 /* *************************************************************************
0216 * Query operations
0217 **************************************************************************/
0218
0219 /**
0220 * Return the child node at the given {@code path}. A path consists of the
0221 * child index at a give level, starting with level 1. (The root note has
0222 * level zero.) {@code tree.childAtPath(Path.of(2))} will return the third
0223 * child node of {@code this} node, if it exists and
0224 * {@code tree.childAtPath(Path.of(2, 0))} will return the first child of
0225 * the third child of {@code this node}.
0226 *
0227 * @since 4.4
0228 *
0229 * @see #childAtPath(int...)
0230 *
0231 * @param path the child path
0232 * @return the child node at the given {@code path}
0233 * @throws NullPointerException if the given {@code path} array is
0234 * {@code null}
0235 */
0236 default Optional<T> childAtPath(final Path path) {
0237 T node = Trees.self(this);
0238 for (int i = 0; i < path.length() && node != null; ++i) {
0239 node = path.get(i) < node.childCount()
0240 ? node.childAt(path.get(i))
0241 : null;
0242 }
0243
0244 return Optional.ofNullable(node);
0245 }
0246
0247 /**
0248 * Return the child node at the given {@code path}. A path consists of the
0249 * child index at a give level, starting with level 1. (The root note has
0250 * level zero.) {@code tree.childAtPath(2)} will return the third child node
0251 * of {@code this} node, if it exists and {@code tree.childAtPath(2, 0)} will
0252 * return the first child of the third child of {@code this node}.
0253 *
0254 * @since 4.3
0255 *
0256 * @see #childAtPath(Path)
0257 *
0258 * @param path the child path
0259 * @return the child node at the given {@code path}
0260 * @throws NullPointerException if the given {@code path} array is
0261 * {@code null}
0262 * @throws IllegalArgumentException if one of the path elements is smaller
0263 * than zero
0264 */
0265 default Optional<T> childAtPath(final int... path) {
0266 return childAtPath(Path.of(path));
0267 }
0268
0269 /**
0270 * Return {@code true} if the given {@code node} is an ancestor of
0271 * {@code this} node. This operation is at worst {@code O(h)} where {@code h}
0272 * is the distance from the root to {@code this} node.
0273 *
0274 * @param node the node to test
0275 * @return {@code true} if the given {@code node} is an ancestor of
0276 * {@code this} node, {@code false} otherwise
0277 * @throws NullPointerException if the given {@code node} is {@code null}
0278 */
0279 default boolean isAncestor(final Tree<?, ?> node) {
0280 requireNonNull(node);
0281
0282 Optional<T> ancestor = Optional.of(Trees.self(this));
0283 boolean result;
0284 do {
0285 result = ancestor.filter(a -> a.identical(node)).isPresent();
0286 } while (!result &&
0287 (ancestor = ancestor.flatMap(Tree<V, T>::parent)).isPresent());
0288
0289 return result;
0290 }
0291
0292 /**
0293 * Return {@code true} if the given {@code node} is a descendant of
0294 * {@code this} node. If the given {@code node} is {@code null},
0295 * {@code false} is returned. This operation is at worst {@code O(h)} where
0296 * {@code h} is the distance from the root to {@code this} node.
0297 *
0298 * @param node the node to test as descendant of this node
0299 * @return {@code true} if this node is an ancestor of the given {@code node}
0300 * @throws NullPointerException if the given {@code node} is {@code null}
0301 */
0302 default boolean isDescendant(final Tree<?, ?> node) {
0303 return requireNonNull(node).isAncestor(this);
0304 }
0305
0306 /**
0307 * Returns the nearest common ancestor to this node and the given {@code node}.
0308 * A node is considered an ancestor of itself.
0309 *
0310 * @param node {@code node} to find common ancestor with
0311 * @return nearest ancestor common to this node and the given {@code node},
0312 * or {@link Optional#empty()} if no common ancestor exists.
0313 * @throws NullPointerException if the given {@code node} is {@code null}
0314 */
0315 default Optional<T> sharedAncestor(final Tree<?, ?> node) {
0316 requireNonNull(node);
0317
0318 T ancestor = null;
0319 if (node.identical(this)) {
0320 ancestor = Trees.self(this);
0321 } else {
0322 final int level1 = level();
0323 final int level2 = node.level();
0324
0325 Tree<?, ?> node1;
0326 Tree<?, ?> node2;
0327 int diff;
0328 if (level2 > level1) {
0329 diff = level2 - level1;
0330 node1 = node;
0331 node2 = Trees.self(this);
0332 } else {
0333 diff = level1 - level2;
0334 node1 = Trees.self(this);
0335 node2 = node;
0336 }
0337
0338 while (diff > 0 && node1 != null) {
0339 node1 = node1.parent().orElse(null);
0340 --diff;
0341 }
0342
0343 do {
0344 if (node1 != null && node1.identical(node2)) {
0345 ancestor = Trees.self(node1);
0346 }
0347 node1 = node1 != null
0348 ? node1.parent().orElse(null)
0349 : null;
0350 node2 = node2.parent().orElse(null);
0351 } while (node1 != null && node2 != null && ancestor == null);
0352 }
0353
0354 return Optional.ofNullable(ancestor);
0355 }
0356
0357 /**
0358 * Returns true if and only if the given {@code node} is in the same tree as
0359 * {@code this} node.
0360 *
0361 * @param node the other node to check
0362 * @return true if the given {@code node} is in the same tree as {@code this}
0363 * node, {@code false} otherwise.
0364 * @throws NullPointerException if the given {@code node} is {@code null}
0365 */
0366 default boolean isRelated(final Tree<?, ?> node) {
0367 requireNonNull(node);
0368 return node.root().identical(root());
0369 }
0370
0371 /**
0372 * Returns the path from the root, to get to this node. The last element in
0373 * the path is this node.
0374 *
0375 * @return an array of TreeNode objects giving the path, where the
0376 * first element in the path is the root and the last
0377 * element is this node.
0378 * @deprecated Use {@link #pathElements()} instead
0379 */
0380 @Deprecated
0381 default ISeq<T> getPath() {
0382 return Trees.pathElementsFromRoot(Trees.<V, T>self(this), 0).toISeq();
0383 }
0384
0385 /**
0386 * Returns the path from the root, to get to this node. The last element in
0387 * the path is this node.
0388 *
0389 * @since 5.1
0390 *
0391 * @return an array of TreeNode objects giving the path, where the
0392 * first element in the path is the root and the last
0393 * element is this node.
0394 */
0395 default ISeq<T> pathElements() {
0396 return Trees.pathElementsFromRoot(Trees.<V, T>self(this), 0).toISeq();
0397 }
0398
0399 /**
0400 * Return the {@link Path} of {@code this} tree, such that
0401 * <pre>{@code
0402 * final Tree<Integer, ?> tree = ...;
0403 * final Tree.Path path = tree.path();
0404 * assert tree == tree.getRoot()
0405 * .childAtPath(path)
0406 * .orElse(null);
0407 * }</pre>
0408 *
0409 * @since 5.1
0410 *
0411 * @return the path from the root element to {@code this} node.
0412 */
0413 default Path path() {
0414 final int[] p = Trees.pathFromRoot(Trees.<V, T>self(this), 0);
0415 return Path.of(p);
0416 }
0417
0418 /**
0419 * Returns the root of the tree that contains this node. The root is the
0420 * ancestor with no parent.
0421 *
0422 * @return the root of the tree that contains this node
0423 */
0424 default T root() {
0425 return getRoot();
0426 }
0427
0428 /**
0429 * Returns the root of the tree that contains this node. The root is the
0430 * ancestor with no parent.
0431 *
0432 * @return the root of the tree that contains this node
0433 * @deprecated
0434 */
0435 @Deprecated
0436 default T getRoot() {
0437 T anc = Trees.self(this);
0438 T prev;
0439
0440 do {
0441 prev = anc;
0442 anc = anc.parent().orElse(null);
0443 } while (anc != null);
0444
0445 return prev;
0446 }
0447
0448 /* *************************************************************************
0449 * Child query operations
0450 **************************************************************************/
0451
0452 /**
0453 * Return {@code true} if the given {@code node} is a child of {@code this}
0454 * node.
0455 *
0456 * @param node the other node to check
0457 * @return {@code true} if {@code node}is a child, {@code false} otherwise
0458 * @throws NullPointerException if the given {@code node} is {@code null}
0459 */
0460 default boolean isChild(final Tree<?, ?> node) {
0461 requireNonNull(node);
0462 return childCount() != 0 &&
0463 node.parent().equals(Optional.of(Trees.<V, T>self(this)));
0464 }
0465
0466 /**
0467 * Return the first child of {@code this} node, or {@code Optional.empty()}
0468 * if {@code this} node has no children.
0469 *
0470 * @return the first child of this node
0471 */
0472 default Optional<T> firstChild() {
0473 return childCount() > 0
0474 ? Optional.of(childAt(0))
0475 : Optional.empty();
0476 }
0477
0478 /**
0479 * Return the last child of {@code this} node, or {@code Optional.empty()}
0480 * if {@code this} node has no children.
0481 *
0482 * @return the last child of this node
0483 */
0484 default Optional<T> lastChild() {
0485 return childCount() > 0
0486 ? Optional.of(childAt(childCount() - 1))
0487 : Optional.empty();
0488 }
0489
0490 /**
0491 * Return the child which comes immediately after {@code this} node. This
0492 * method performs a linear search of this node's children for {@code child}
0493 * and is {@code O(n)} where n is the number of children.
0494 *
0495 * @param child the child node
0496 * @return the child of this node that immediately follows the {@code child},
0497 * or {@code Optional.empty()} if the given {@code node} is the
0498 * first node.
0499 * @throws NullPointerException if the given {@code child} is {@code null}
0500 */
0501 default Optional<T> childAfter(final Tree<?, ?> child) {
0502 requireNonNull(child);
0503
0504 final int index = indexOf(child);
0505 if (index == -1) {
0506 throw new IllegalArgumentException("The given node is not a child.");
0507 }
0508
0509 return index < childCount() - 1
0510 ? Optional.of(childAt(index + 1))
0511 : Optional.empty();
0512 }
0513
0514 /**
0515 * Return the child which comes immediately before {@code this} node. This
0516 * method performs a linear search of this node's children for {@code child}
0517 * and is {@code O(n)} where n is the number of children.
0518 *
0519 * @param child the child node
0520 * @return the child of this node that immediately precedes the {@code child},
0521 * or {@code null} if the given {@code node} is the first node.
0522 * @throws NullPointerException if the given {@code child} is {@code null}
0523 */
0524 default Optional<T> childBefore(final Tree<?, ?> child) {
0525 requireNonNull(child);
0526
0527 final int index = indexOf(child);
0528 if (index == -1) {
0529 throw new IllegalArgumentException("The given node is not a child.");
0530 }
0531
0532 return index > 0
0533 ? Optional.of(childAt(index - 1))
0534 : Optional.empty();
0535 }
0536
0537 /**
0538 * Return the node that follows {@code this} node in a pre-order traversal
0539 * of {@code this} tree node. Return {@code Optional.empty()} if this node
0540 * is the last node of the traversal. This is an inefficient way to traverse
0541 * the entire tree use an iterator instead.
0542 *
0543 * @see #preorderIterator
0544 * @return the node that follows this node in a pre-order traversal, or
0545 * {@code Optional.empty()} if this node is last
0546 */
0547 default Optional<T> nextNode() {
0548 Optional<T> next = Optional.empty();
0549
0550 if (childCount() == 0) {
0551 T node = Trees.self(this);
0552 while (node != null && !(next = node.nextSibling()).isPresent()) {
0553 node = node.parent().orElse(null);
0554 }
0555 } else {
0556 next = Optional.of(childAt(0));
0557 }
0558
0559 return next;
0560 }
0561
0562 /**
0563 * Return the node that precedes this node in a pre-order traversal of
0564 * {@code this} tree node. Returns {@code Optional.empty()} if this node is
0565 * the first node of the traversal, the root of the tree. This is an
0566 * inefficient way to traverse the entire tree; use an iterator instead.
0567 *
0568 * @see #preorderIterator
0569 * @return the node that precedes this node in a pre-order traversal, or
0570 * {@code Optional.empty()} if this node is the first
0571 */
0572 default Optional<T> previousNode() {
0573 Optional<T> node = Optional.empty();
0574
0575 if (parent().isPresent()) {
0576 final Optional<T> prev = previousSibling();
0577 if (prev.isPresent()) {
0578 node = prev.get().childCount() == 0
0579 ? prev
0580 : prev.map(Tree<V, T>::lastLeaf);
0581 } else {
0582 node = parent();
0583 }
0584 }
0585
0586 return node;
0587 }
0588
0589 /* *************************************************************************
0590 * Sibling query operations
0591 **************************************************************************/
0592
0593 /**
0594 * Test if the given {@code node} is a sibling of {@code this} node.
0595 *
0596 * @param node node to test as sibling of this node
0597 * @return {@code true} if the {@code node} is a sibling of {@code this}
0598 * node
0599 * @throws NullPointerException if the given {@code node} is {@code null}
0600 */
0601 default boolean isSibling(final Tree<?, ?> node) {
0602 return identical(requireNonNull(node)) ||
0603 parent().equals(node.parent());
0604 }
0605
0606 /**
0607 * Return the number of siblings of {@code this} node. A node is its own
0608 * sibling (if it has no parent or no siblings, this method returns
0609 * {@code 1}).
0610 *
0611 * @return the number of siblings of {@code this} node
0612 */
0613 default int siblingCount() {
0614 return parent().map(Tree<V, T>::childCount).orElse(1);
0615 }
0616
0617 /**
0618 * Return the next sibling of {@code this} node in the parent's children
0619 * array, or {@code null} if {@code this} node has no parent or it is the
0620 * last child of the paren. This method performs a linear search that is
0621 * {@code O(n)} where n is the number of children; to traverse the entire
0622 * array, use the iterator of the parent instead.
0623 *
0624 * @see #childStream()
0625 * @return the sibling of {@code this} node that immediately follows
0626 * {@code this} node
0627 */
0628 default Optional<T> nextSibling() {
0629 return parent().flatMap(p -> p.childAfter(Trees.<V, T>self(this)));
0630 }
0631
0632 /**
0633 * Return the previous sibling of {@code this} node in the parent's children
0634 * list, or {@code Optional.empty()} if this node has no parent or is the
0635 * parent's first child. This method performs a linear search that is O(n)
0636 * where n is the number of children.
0637 *
0638 * @return the sibling of {@code this} node that immediately precedes this
0639 * node
0640 */
0641 default Optional<T> previousSibling() {
0642 return parent().flatMap(p -> p.childBefore(Trees.<V, T>self(this)));
0643 }
0644
0645
0646 /* *************************************************************************
0647 * Leaf query operations
0648 **************************************************************************/
0649
0650 /**
0651 * Return {@code true} if {@code this} node has no children.
0652 *
0653 * @return {@code true} if {@code this} node has no children, {@code false}
0654 * otherwise
0655 */
0656 default boolean isLeaf() {
0657 return childCount() == 0;
0658 }
0659
0660 /**
0661 * Return the first leaf that is a descendant of {@code this} node; either
0662 * this node or its first child's first leaf. {@code this} node is returned
0663 * if it is a leaf.
0664 *
0665 * @see #isLeaf
0666 * @see #isDescendant
0667 * @return the first leaf in the subtree rooted at this node
0668 */
0669 default T firstLeaf() {
0670 T leaf = Trees.self(this);
0671 while (!leaf.isLeaf()) {
0672 leaf = leaf.firstChild().orElseThrow(AssertionError::new);
0673 }
0674
0675 return leaf;
0676 }
0677
0678 /**
0679 * Return the last leaf that is a descendant of this node; either
0680 * {@code this} node or its last child's last leaf. Returns {@code this}
0681 * node if it is a leaf.
0682 *
0683 * @see #isLeaf
0684 * @see #isDescendant
0685 * @return the last leaf in this subtree
0686 */
0687 default T lastLeaf() {
0688 T leaf = Trees.self(this);
0689 while (!leaf.isLeaf()) {
0690 leaf = leaf.lastChild().orElseThrow(AssertionError::new);
0691 }
0692
0693 return leaf;
0694 }
0695
0696 /**
0697 * Returns the leaf after {@code this} node or {@code Optional.empty()} if
0698 * this node is the last leaf in the tree.
0699 * <p>
0700 * In order to determine the next node, this method first performs a linear
0701 * search in the parent's child-list in order to find the current node.
0702 * <p>
0703 * That implementation makes the operation suitable for short traversals
0704 * from a known position. But to traverse all of the leaves in the tree, you
0705 * should use {@link #depthFirstIterator()} to iterator the nodes in the
0706 * tree and use {@link #isLeaf()} on each node to determine which are leaves.
0707 *
0708 * @see #depthFirstIterator
0709 * @see #isLeaf
0710 * @return return the next leaf past this node
0711 */
0712 default Optional<T> nextLeaf() {
0713 return nextSibling()
0714 .map(s -> Optional.of(s.firstLeaf()))
0715 .orElseGet(() -> parent().flatMap(Tree<V, T>::nextLeaf));
0716 }
0717
0718 /**
0719 * Return the leaf before {@code this} node or {@code null} if {@code this}
0720 * node is the first leaf in the tree.
0721 * <p>
0722 * In order to determine the previous node, this method first performs a
0723 * linear search in the parent's child-list in order to find the current
0724 * node.
0725 * <p>
0726 * That implementation makes the operation suitable for short traversals
0727 * from a known position. But to traverse all of the leaves in the tree, you
0728 * should use {@link #depthFirstIterator()} to iterate the nodes in the tree
0729 * and use {@link #isLeaf()} on each node to determine which are leaves.
0730 *
0731 * @see #depthFirstIterator
0732 * @see #isLeaf
0733 * @return returns the leaf before {@code this} node
0734 */
0735 default Optional<T> previousLeaf() {
0736 return previousSibling()
0737 .map(s -> Optional.of(s.lastLeaf()))
0738 .orElseGet(() -> parent().flatMap(Tree<V, T>::previousLeaf));
0739 }
0740
0741 /**
0742 * Returns the total number of leaves that are descendants of this node.
0743 * If this node is a leaf, returns {@code 1}. This method is {@code O(n)},
0744 * where n is the number of descendants of {@code this} node.
0745 *
0746 * @see #isLeaf()
0747 * @return the number of leaves beneath this node
0748 */
0749 default int leafCount() {
0750 return (int)breadthFirstStream()
0751 .filter(Tree<V, T>::isLeaf)
0752 .count();
0753 }
0754
0755 /* *************************************************************************
0756 * Tree traversing.
0757 **************************************************************************/
0758
0759 /**
0760 * Return an iterator that traverses the subtree rooted at {@code this}
0761 * node in breadth-first order. The first node returned by the iterator is
0762 * {@code this} node.
0763 * <p>
0764 * Modifying the tree by inserting, removing, or moving a node invalidates
0765 * any iterator created before the modification.
0766 *
0767 * @see #depthFirstIterator
0768 * @return an iterator for traversing the tree in breadth-first order
0769 */
0770 default Iterator<T> breadthFirstIterator() {
0771 return new TreeNodeBreadthFirstIterator<>(Trees.<V, T>self(this));
0772 }
0773
0774 /**
0775 * Return an iterator that traverses the subtree rooted at {@code this}.
0776 * The first node returned by the iterator is {@code this} node.
0777 * <p>
0778 * Modifying the tree by inserting, removing, or moving a node invalidates
0779 * any iterator created before the modification.
0780 *
0781 * @see #breadthFirstIterator
0782 * @return an iterator for traversing the tree in breadth-first order
0783 */
0784 @Override
0785 default Iterator<T> iterator() {
0786 return breadthFirstIterator();
0787 }
0788
0789 /**
0790 * Return a stream that traverses the subtree rooted at {@code this} node in
0791 * breadth-first order. The first node returned by the stream is
0792 * {@code this} node.
0793 *
0794 * @see #depthFirstIterator
0795 * @see #stream()
0796 * @return a stream for traversing the tree in breadth-first order
0797 */
0798 default Stream<T> breadthFirstStream() {
0799 return StreamSupport
0800 .stream(spliteratorUnknownSize(breadthFirstIterator(), 0), false);
0801 }
0802
0803 /**
0804 * Return a stream that traverses the subtree rooted at {@code this} node in
0805 * breadth-first order. The first node returned by the stream is
0806 * {@code this} node.
0807 *
0808 * @see #breadthFirstStream
0809 * @return a stream for traversing the tree in breadth-first order
0810 */
0811 default Stream<T> stream() {
0812 return breadthFirstStream();
0813 }
0814
0815 /**
0816 * Return an iterator that traverses the subtree rooted at {@code this} node
0817 * in pre-order. The first node returned by the iterator is {@code this}
0818 * node.
0819 * <p>
0820 * Modifying the tree by inserting, removing, or moving a node invalidates
0821 * any iterator created before the modification.
0822 *
0823 * @see #postorderIterator
0824 * @return an iterator for traversing the tree in pre-order
0825 */
0826 default Iterator<T> preorderIterator() {
0827 return new TreeNodePreorderIterator<>(Trees.<V, T>self(this));
0828 }
0829
0830 /**
0831 * Return a stream that traverses the subtree rooted at {@code this} node
0832 * in pre-order. The first node returned by the stream is {@code this} node.
0833 * <p>
0834 * Modifying the tree by inserting, removing, or moving a node invalidates
0835 * any iterator created before the modification.
0836 *
0837 * @see #preorderIterator
0838 * @return a stream for traversing the tree in pre-order
0839 */
0840 default Stream<T> preorderStream() {
0841 return StreamSupport
0842 .stream(spliteratorUnknownSize(preorderIterator(), 0), false);
0843 }
0844
0845 /**
0846 * Return an iterator that traverses the subtree rooted at {@code this}
0847 * node in post-order. The first node returned by the iterator is the
0848 * leftmost leaf. This is the same as a depth-first traversal.
0849 *
0850 * @see #depthFirstIterator
0851 * @see #preorderIterator
0852 * @return an iterator for traversing the tree in post-order
0853 */
0854 default Iterator<T> postorderIterator() {
0855 return new TreeNodePostorderIterator<>(Trees.<V, T>self(this));
0856 }
0857
0858 /**
0859 * Return a stream that traverses the subtree rooted at {@code this} node in
0860 * post-order. The first node returned by the iterator is the leftmost leaf.
0861 * This is the same as a depth-first traversal.
0862 *
0863 * @see #depthFirstIterator
0864 * @see #preorderIterator
0865 * @return a stream for traversing the tree in post-order
0866 */
0867 default Stream<T> postorderStream() {
0868 return StreamSupport
0869 .stream(spliteratorUnknownSize(postorderIterator(), 0), false);
0870 }
0871
0872 /**
0873 * Return an iterator that traverses the subtree rooted at {@code this} node
0874 * in depth-first order. The first node returned by the iterator is the
0875 * leftmost leaf. This is the same as a postorder traversal.
0876 * <p>
0877 * Modifying the tree by inserting, removing, or moving a node invalidates
0878 * any iterator created before the modification.
0879 *
0880 * @see #breadthFirstIterator
0881 * @see #postorderIterator
0882 * @return an iterator for traversing the tree in depth-first order
0883 */
0884 default Iterator<T> depthFirstIterator() {
0885 return postorderIterator();
0886 }
0887
0888 /**
0889 * Return a stream that traverses the subtree rooted at {@code this} node in
0890 * depth-first. The first node returned by the iterator is the leftmost leaf.
0891 * This is the same as a post-order traversal.
0892 *
0893 * @see #depthFirstIterator
0894 * @see #preorderIterator
0895 * @return a stream for traversing the tree in post-order
0896 */
0897 default Stream<T> depthFirstStream() {
0898 return postorderStream();
0899 }
0900
0901 /**
0902 * Return an iterator that follows the path from {@code ancestor} to
0903 * {@code this} node. The iterator return {@code ancestor} as first element,
0904 * The creation of the iterator is O(m), where m is the number of nodes
0905 * between {@code this} node and the {@code ancestor}, inclusive.
0906 * <p>
0907 * Modifying the tree by inserting, removing, or moving a node invalidates
0908 * any iterator created before the modification.
0909 *
0910 * @see #isAncestor
0911 * @see #isDescendant
0912 * @param ancestor the ancestor node
0913 * @return an iterator for following the path from an ancestor of {@code this}
0914 * node to this one
0915 * @throws IllegalArgumentException if the {@code ancestor} is not an
0916 * ancestor of this node
0917 * @throws NullPointerException if the given {@code ancestor} is {@code null}
0918 */
0919 default Iterator<T> pathFromAncestorIterator(final Tree<?, ?> ancestor) {
0920 return new TreeNodePathIterator<>(ancestor, Trees.<V, T>self(this));
0921 }
0922
0923 /**
0924 * Return the path of {@code this} child node from the root node. You will
0925 * get {@code this} node, if you call {@link #childAtPath(Path)} on the
0926 * root node of {@code this} node.
0927 * <pre>{@code
0928 * final Tree<?, ?> node = ...;
0929 * final Tree<?, ?> root = node.getRoot();
0930 * final int[] path = node.childPath();
0931 * assert node == root.childAtPath(path);
0932 * }</pre>
0933 *
0934 * @since 4.4
0935 *
0936 * @see #childAtPath(Path)
0937 *
0938 * @return the path of {@code this} child node from the root node.
0939 */
0940 default Path childPath() {
0941 final Iterator<T> it = pathFromAncestorIterator(root());
0942 final int[] path = new int[level()];
0943
0944 T tree = null;
0945 int index = 0;
0946 while (it.hasNext()) {
0947 final T child = it.next();
0948 if (tree != null) {
0949 path[index++] = tree.indexOf(child);
0950 }
0951
0952 tree = child;
0953 }
0954
0955 assert index == path.length;
0956
0957 return new Path(path);
0958 }
0959
0960 /**
0961 * Tests whether {@code this} node is the same as the {@code other} node.
0962 * The default implementation returns the object identity,
0963 * {@code this == other}, of the two objects, but other implementations may
0964 * use different criteria for checking the <i>identity</i>.
0965 *
0966 * @param other the {@code other} node
0967 * @return {@code true} if the {@code other} node is the same as {@code this}
0968 * node.
0969 */
0970 default boolean identical(final Tree<?, ?> other) {
0971 return this == other;
0972 }
0973
0974 /* *************************************************************************
0975 * 'toString' methods
0976 **************************************************************************/
0977
0978 /**
0979 * Return a compact string representation of the given tree. The tree
0980 * <pre>
0981 * mul
0982 * ├── div
0983 * │ ├── cos
0984 * │ │ └── 1.0
0985 * │ └── cos
0986 * │ └── π
0987 * └── sin
0988 * └── mul
0989 * ├── 1.0
0990 * └── z
0991 * </pre>
0992 * is printed as
0993 * <pre>
0994 * mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
0995 * </pre>
0996 *
0997 * @since 4.3
0998 *
0999 * @see #toParenthesesString()
1000 * @see TreeFormatter#PARENTHESES
1001 *
1002 * @param mapper the {@code mapper} which converts the tree value to a string
1003 * @return the string representation of the given tree
1004 */
1005 default String toParenthesesString(final Function<? super V, String> mapper) {
1006 return TreeFormatter.PARENTHESES.format(this, mapper);
1007 }
1008
1009 /**
1010 * Return a compact string representation of the given tree. The tree
1011 * <pre>
1012 * mul
1013 * ├── div
1014 * │ ├── cos
1015 * │ │ └── 1.0
1016 * │ └── cos
1017 * │ └── π
1018 * └── sin
1019 * └── mul
1020 * ├── 1.0
1021 * └── z
1022 * </pre>
1023 * is printed as
1024 * <pre>
1025 * mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
1026 * </pre>
1027 *
1028 * @since 4.3
1029 *
1030 * @see #toParenthesesString(Function)
1031 * @see TreeFormatter#PARENTHESES
1032 *
1033 * @return the string representation of the given tree
1034 * @throws NullPointerException if the {@code mapper} is {@code null}
1035 */
1036 default String toParenthesesString() {
1037 return toParenthesesString(Objects::toString);
1038 }
1039
1040 /* *************************************************************************
1041 * Static helper methods.
1042 **************************************************************************/
1043
1044 /**
1045 * Calculates the hash code of the given tree.
1046 *
1047 * @param tree the tree where the hash is calculated from
1048 * @return the hash code of the tree
1049 * @throws NullPointerException if the given {@code tree} is {@code null}
1050 */
1051 static int hashCode(final Tree<?, ?> tree) {
1052 return tree != null
1053 ? tree.breadthFirstStream()
1054 .mapToInt(node -> 31*Objects.hashCode(node.value()) + 37)
1055 .sum() + 17
1056 : 0;
1057 }
1058
1059 /**
1060 * Checks if the two given trees has the same structure with the same values.
1061 *
1062 * @param a the first tree
1063 * @param b the second tree
1064 * @return {@code true} if the two given trees are structurally equals,
1065 * {@code false} otherwise
1066 */
1067 static boolean equals(final Tree<?, ?> a, final Tree<?, ?> b) {
1068 return Trees.equals(a, b);
1069 }
1070
1071 /**
1072 * Return a string representation of the given tree, like the following
1073 * example.
1074 *
1075 * <pre>
1076 * mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
1077 * </pre>
1078 *
1079 * This method is intended to be used when override the
1080 * {@link Object#toString()} method.
1081 *
1082 * @param tree the input tree
1083 * @return the string representation of the given tree
1084 */
1085 static String toString(final Tree<?, ?> tree) {
1086 return tree.toParenthesesString();
1087 }
1088
1089
1090 /* *************************************************************************
1091 * Inner classes
1092 **************************************************************************/
1093
1094 /**
1095 * This class represents the path to child within a given tree. It allows to
1096 * point (and fetch) a tree child.
1097 *
1098 * @see Tree#childAtPath(Path)
1099 *
1100 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
1101 * @version 4.4
1102 * @since 4.4
1103 */
1104 final class Path implements Serializable {
1105 private static final long serialVersionUID = 1L;
1106
1107 private final int[] _path;
1108
1109 private Path(final int[] path) {
1110 _path = requireNonNull(path);
1111 }
1112
1113 /**
1114 * Return the path length, which is the level of the child {@code this}
1115 * path points to.
1116 *
1117 * @return the path length
1118 */
1119 public int length() {
1120 return _path.length;
1121 }
1122
1123 /**
1124 * Return the child index at the given index (child level).
1125 *
1126 * @param index the path index
1127 * @return the child index at the given child level
1128 * @throws IndexOutOfBoundsException if the index is not with the range
1129 * {@code [0, length())}
1130 */
1131 public int get(final int index) {
1132 return _path[index];
1133 }
1134
1135 /**
1136 * Return the path as {@code int[]} array.
1137 *
1138 * @return the path as {@code int[]} array
1139 */
1140 public int[] toArray() {
1141 return _path.clone();
1142 }
1143
1144 /**
1145 * Appends the given {@code path} to {@code this} one.
1146 *
1147 * @param path the path to append
1148 * @return a new {@code Path} with the given {@code path} appended
1149 * @throws NullPointerException if the given {@code path} is {@code null}
1150 */
1151 public Path append(final Path path) {
1152 final int[] p = new int[length() + path.length()];
1153 System.arraycopy(_path, 0, p, 0, length());
1154 System.arraycopy(path._path, 0, p, length(), path.length());
1155 return new Path(p);
1156 }
1157
1158 @Override
1159 public int hashCode() {
1160 return Arrays.hashCode(_path);
1161 }
1162
1163 @Override
1164 public boolean equals(final Object obj) {
1165 return obj == this ||
1166 obj instanceof Path &&
1167 Arrays.equals(_path, ((Path)obj)._path);
1168 }
1169
1170 @Override
1171 public String toString() {
1172 return Arrays.toString(_path);
1173 }
1174
1175 /**
1176 * Create a new path object from the given child indexes.
1177 *
1178 * @param path the child indexes
1179 * @return a new tree path
1180 * @throws IllegalArgumentException if one of the path elements is
1181 * smaller than zero
1182 */
1183 public static Path of(final int... path) {
1184 for (int i = 0; i < path.length; ++i) {
1185 if (path[i] < 0) {
1186 throw new IllegalArgumentException(format(
1187 "Path element at position %d is smaller than zero: %d",
1188 i, path[i]
1189 ));
1190 }
1191 }
1192
1193 return new Path(path.clone());
1194 }
1195 }
1196
1197 }
|