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