Tree.java
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(this1;
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 > && 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() != &&
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[i0) {
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 }