001/*
002 * Java Genetic Algorithm Library (jenetics-5.2.0).
003 * Copyright (c) 2007-2020 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020package io.jenetics.ext.util;
021
022import static java.lang.String.format;
023import static java.util.Objects.requireNonNull;
024import static java.util.Spliterators.spliteratorUnknownSize;
025
026import java.io.Serializable;
027import java.util.Arrays;
028import java.util.Iterator;
029import java.util.Objects;
030import java.util.Optional;
031import java.util.function.Function;
032import java.util.stream.Stream;
033import java.util.stream.StreamSupport;
034
035import io.jenetics.util.ISeq;
036
037/**
038 * General purpose tree structure. The interface only contains tree read methods.
039 * For a mutable tree implementation have a look at the {@link TreeNode} class.
040 *
041 * @see TreeNode
042 *
043 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
044 * @version 5.2
045 * @since 3.9
046 */
047public interface Tree<V, T extends Tree<V, T>> extends Iterable<T> {
048
049        /* *************************************************************************
050         * Basic (abstract) operations. All other tree operations can be derived
051         * from this methods.
052         **************************************************************************/
053
054        /**
055         * Return the value of the current {@code Tree} node. The value may be
056         * {@code null}.
057         *
058         * @return the value of the current {@code Tree} node
059         */
060        default V value() {
061                return getValue();
062        }
063
064        /**
065         * Return the value of the current {@code Tree} node. The value may be
066         * {@code null}.
067         *
068         * @return the value of the current {@code Tree} node
069         * @deprecated Use {@link #value()} instead
070         */
071        @Deprecated
072        V getValue();
073
074        /**
075         * Return the <em>parent</em> node of this tree node.
076         *
077         * @return the parent node, or {@code Optional.empty()} if this node is the
078         *         root of the tree
079         */
080        default Optional<T> parent() {
081                return getParent();
082        }
083
084        /**
085         * Return the <em>parent</em> node of this tree node.
086         *
087         * @return the parent node, or {@code Optional.empty()} if this node is the
088         *         root of the tree
089         * @deprecated Use {@link #parent()} instead
090         */
091        @Deprecated
092        Optional<T> getParent();
093
094        /**
095         * Return the child node with the given index.
096         *
097         * @param index the child index
098         * @return the child node with the given index
099         * @throws IndexOutOfBoundsException  if the {@code index} is out of
100         *         bounds ({@code [0, childCount())})
101         */
102        T childAt(final int index);
103
104        /**
105         * Return the number of children this tree node consists of.
106         *
107         * @return the number of children this tree node consists of
108         */
109        int childCount();
110
111
112        /* *************************************************************************
113         * Derived operations
114         **************************************************************************/
115
116        /**
117         * Return an iterator of the children of this {@code Tree} node.
118         *
119         * @return an iterator of the children of this {@code Tree} node.
120         */
121        default Iterator<T> childIterator() {
122                return new TreeChildIterator<V, T>(Trees.self(this));
123        }
124
125        /**
126         * Return a forward-order stream of this node's children.
127         *
128         * @return a stream of children of {@code this} node
129         */
130        default Stream<T> childStream() {
131                return StreamSupport
132                        .stream(spliteratorUnknownSize(childIterator(), 0), false);
133        }
134
135        /**
136         * Returns {@code true} if this node is the root of the tree.
137         *
138         * @return {@code true} if this node is the root of its tree, {@code false}
139         *         otherwise
140         */
141        default boolean isRoot() {
142                return !parent().isPresent();
143        }
144
145        /**
146         * Returns the depth of the tree rooted at this node. The <i>depth</i> of a
147         * tree is the longest distance from {@code this} node to a leaf. If
148         * {@code this} node has no children, 0 is returned. This operation is much
149         * more expensive than {@link #level()} because it must effectively traverse
150         * the entire tree rooted at {@code this} node.
151         *
152         * @return the depth of the tree whose root is this node
153         */
154        default int depth() {
155                final Iterator<T> it = breadthFirstIterator();
156
157                T last = null;
158                while (it.hasNext()) {
159                        last = it.next();
160                }
161
162                assert last != null;
163                return last.level() - level();
164        }
165
166        /**
167         * Returns the number of levels above this node. The <i>level</i> of a tree
168         * is the distance from the root to {@code this} node. If {@code this} node
169         * is the root, returns 0.
170         *
171         * @return the number of levels above this node
172         */
173        default int level() {
174                Optional<T> ancestor = Optional.of(Trees.self(this));
175                int levels = 0;
176                while ((ancestor = ancestor.flatMap(Tree<V, T>::parent)).isPresent()) {
177                        ++levels;
178                }
179
180                return levels;
181        }
182
183        /**
184         * Returns the index of the specified child in this node's child array, or
185         * {@code -1} if {@code this} node doesn't contain the given {@code child}.
186         * This method performs a linear search and is O(n) where {@code n} is the
187         * number of children.
188         *
189         * @param child  the TreeNode to search for among this node's children
190         * @throws NullPointerException if the given {@code child} is {@code null}
191         * @return the index of the node in this node's child array, or {@code -1}
192         *         if the node could not be found
193         */
194        default int indexOf(final Tree<?, ?> child) {
195                int index = -1;
196                for (int i = 0, n = childCount(); i < n && index == -1; ++i) {
197                        if (childAt(i).identical(child)) {
198                                index = i;
199                        }
200                }
201
202                return index;
203        }
204
205        /**
206         * Return the number of nodes of {@code this} node (sub-tree).
207         *
208         * @return the number of nodes of {@code this} node (sub-tree)
209         */
210        default int size() {
211                return Trees.countChildren(this) + 1;
212        }
213
214
215        /* *************************************************************************
216         * Query operations
217         **************************************************************************/
218
219        /**
220         * Return the child node at the given {@code path}. A path consists of the
221         * child index at a give level, starting with level 1. (The root note has
222         * level zero.) {@code tree.childAtPath(Path.of(2))} will return the third
223         * child node of {@code this} node, if it exists and
224         * {@code tree.childAtPath(Path.of(2, 0))} will return the first child of
225         * the third child of {@code this node}.
226         *
227         * @since 4.4
228         *
229         * @see #childAtPath(int...)
230         *
231         * @param path the child path
232         * @return the child node at the given {@code path}
233         * @throws NullPointerException if the given {@code path} array is
234         *         {@code null}
235         */
236        default Optional<T> childAtPath(final Path path) {
237                T node = Trees.self(this);
238                for (int i = 0; i < path.length() && node != null; ++i) {
239                        node = path.get(i) < node.childCount()
240                                ? node.childAt(path.get(i))
241                                : null;
242                }
243
244                return Optional.ofNullable(node);
245        }
246
247        /**
248         * Return the child node at the given {@code path}. A path consists of the
249         * child index at a give level, starting with level 1. (The root note has
250         * level zero.) {@code tree.childAtPath(2)} will return the third child node
251         * of {@code this} node, if it exists and {@code tree.childAtPath(2, 0)} will
252         * return the first child of the third child of {@code this node}.
253         *
254         * @since 4.3
255         *
256         * @see #childAtPath(Path)
257         *
258         * @param path the child path
259         * @return the child node at the given {@code path}
260         * @throws NullPointerException if the given {@code path} array is
261         *         {@code null}
262         * @throws IllegalArgumentException if one of the path elements is smaller
263         *         than zero
264         */
265        default Optional<T> childAtPath(final int... path) {
266                return childAtPath(Path.of(path));
267        }
268
269        /**
270         * Return {@code true} if the given {@code node} is an ancestor of
271         * {@code this} node. This operation is at worst {@code O(h)} where {@code h}
272         * is the distance from the root to {@code this} node.
273         *
274         * @param node the node to test
275         * @return {@code true} if the given {@code node} is an ancestor of
276         *         {@code this} node, {@code false} otherwise
277         * @throws NullPointerException if the given {@code node} is {@code null}
278         */
279        default boolean isAncestor(final Tree<?, ?> node) {
280                requireNonNull(node);
281
282                Optional<T> ancestor = Optional.of(Trees.self(this));
283                boolean result;
284                do {
285                        result = ancestor.filter(a -> a.identical(node)).isPresent();
286                } while (!result &&
287                                (ancestor = ancestor.flatMap(Tree<V, T>::parent)).isPresent());
288
289                return result;
290        }
291
292        /**
293         * Return {@code true} if the given {@code node} is a descendant of
294         * {@code this} node. If the given {@code node} is {@code null},
295         * {@code false} is returned. This operation is at worst {@code O(h)} where
296         * {@code h} is the distance from the root to {@code this} node.
297         *
298         * @param node the node to test as descendant of this node
299         * @return {@code true} if this node is an ancestor of the given {@code node}
300         * @throws NullPointerException if the given {@code node} is {@code null}
301         */
302        default boolean isDescendant(final Tree<?, ?> node) {
303                return requireNonNull(node).isAncestor(this);
304        }
305
306        /**
307         * Returns the nearest common ancestor to this node and the given {@code node}.
308         * A node is considered an ancestor of itself.
309         *
310         * @param node {@code node} to find common ancestor with
311         * @return nearest ancestor common to this node and the given {@code node},
312         *         or {@link Optional#empty()} if no common ancestor exists.
313         * @throws NullPointerException if the given {@code node} is {@code null}
314         */
315        default Optional<T> sharedAncestor(final Tree<?, ?> node) {
316                requireNonNull(node);
317
318                T ancestor = null;
319                if (node.identical(this)) {
320                        ancestor = Trees.self(this);
321                } else {
322                        final int level1 = level();
323                        final int level2 = node.level();
324
325                        Tree<?, ?> node1;
326                        Tree<?, ?> node2;
327                        int diff;
328                        if (level2 > level1) {
329                                diff = level2 - level1;
330                                node1 = node;
331                                node2 = Trees.self(this);
332                        } else {
333                                diff = level1 - level2;
334                                node1 = Trees.self(this);
335                                node2 = node;
336                        }
337
338                        while (diff > 0 && node1 != null) {
339                                node1 = node1.parent().orElse(null);
340                                --diff;
341                        }
342
343                        do {
344                                if (node1 != null && node1.identical(node2)) {
345                                        ancestor = Trees.self(node1);
346                                }
347                                node1 = node1 != null
348                                        ? node1.parent().orElse(null)
349                                        : null;
350                                node2 = node2.parent().orElse(null);
351                        } while (node1 != null && node2 != null && ancestor == null);
352                }
353
354                return Optional.ofNullable(ancestor);
355        }
356
357        /**
358         * Returns true if and only if the given {@code node} is in the same tree as
359         * {@code this} node.
360         *
361         * @param node the other node to check
362         * @return true if the given {@code node} is in the same tree as {@code this}
363         *         node, {@code false} otherwise.
364         * @throws NullPointerException if the given {@code node} is {@code null}
365         */
366        default boolean isRelated(final Tree<?, ?> node) {
367                requireNonNull(node);
368                return node.root().identical(root());
369        }
370
371        /**
372         * Returns the path from the root, to get to this node. The last element in
373         * the path is this node.
374         *
375         * @return an array of TreeNode objects giving the path, where the
376         *         first element in the path is the root and the last
377         *         element is this node.
378         * @deprecated Use {@link #pathElements()} instead
379         */
380        @Deprecated
381        default ISeq<T> getPath() {
382                return Trees.pathElementsFromRoot(Trees.<V, T>self(this), 0).toISeq();
383        }
384
385        /**
386         * Returns the path from the root, to get to this node. The last element in
387         * the path is this node.
388         *
389         * @since 5.1
390         *
391         * @return an array of TreeNode objects giving the path, where the
392         *         first element in the path is the root and the last
393         *         element is this node.
394         */
395        default ISeq<T> pathElements() {
396                return Trees.pathElementsFromRoot(Trees.<V, T>self(this), 0).toISeq();
397        }
398
399        /**
400         * Return the {@link Path} of {@code this} tree, such that
401         * <pre>{@code
402         * final Tree<Integer, ?> tree = ...;
403         * final Tree.Path path = tree.path();
404         * assert tree == tree.getRoot()
405         *     .childAtPath(path)
406         *     .orElse(null);
407         * }</pre>
408         *
409         * @since 5.1
410         *
411         * @return the path from the root element to {@code this} node.
412         */
413        default Path path() {
414                final int[] p = Trees.pathFromRoot(Trees.<V, T>self(this), 0);
415                return Path.of(p);
416        }
417
418        /**
419         * Returns the root of the tree that contains this node. The root is the
420         * ancestor with no parent.
421         *
422         * @return the root of the tree that contains this node
423         */
424        default T root() {
425                return getRoot();
426        }
427
428        /**
429         * Returns the root of the tree that contains this node. The root is the
430         * ancestor with no parent.
431         *
432         * @return the root of the tree that contains this node
433         * @deprecated
434         */
435        @Deprecated
436        default T getRoot() {
437                T anc = Trees.self(this);
438                T prev;
439
440                do {
441                        prev = anc;
442                        anc = anc.parent().orElse(null);
443                } while (anc != null);
444
445                return prev;
446        }
447
448        /* *************************************************************************
449         * Child query operations
450         **************************************************************************/
451
452        /**
453         * Return {@code true} if the given {@code node} is a child of {@code this}
454         * node.
455         *
456         * @param node the other node to check
457         * @return {@code true} if {@code node}is a child, {@code false} otherwise
458         * @throws NullPointerException if the given {@code node} is {@code null}
459         */
460        default boolean isChild(final Tree<?, ?> node) {
461                requireNonNull(node);
462                return childCount() != 0 &&
463                        node.parent().equals(Optional.of(Trees.<V, T>self(this)));
464        }
465
466        /**
467         * Return the first child of {@code this} node, or {@code Optional.empty()}
468         * if {@code this} node has no children.
469         *
470         * @return the first child of this node
471         */
472        default Optional<T> firstChild() {
473                return childCount() > 0
474                        ? Optional.of(childAt(0))
475                        : Optional.empty();
476        }
477
478        /**
479         * Return the last child of {@code this} node, or {@code Optional.empty()}
480         * if {@code this} node has no children.
481         *
482         * @return the last child of this node
483         */
484        default Optional<T> lastChild() {
485                return childCount() > 0
486                        ? Optional.of(childAt(childCount() - 1))
487                        : Optional.empty();
488        }
489
490        /**
491         * Return the child which comes immediately after {@code this} node. This
492         * method performs a linear search of this node's children for {@code child}
493         * and is {@code O(n)} where n is the number of children.
494         *
495         * @param child the child node
496         * @return  the child of this node that immediately follows the {@code child},
497         *          or {@code Optional.empty()} if the given {@code node} is the
498         *          first node.
499         * @throws NullPointerException if the given {@code child} is {@code null}
500         */
501        default Optional<T> childAfter(final Tree<?, ?> child) {
502                requireNonNull(child);
503
504                final int index = indexOf(child);
505                if (index == -1) {
506                        throw new IllegalArgumentException("The given node is not a child.");
507                }
508
509                return index < childCount() - 1
510                        ? Optional.of(childAt(index + 1))
511                        : Optional.empty();
512        }
513
514        /**
515         * Return the child which comes immediately before {@code this} node. This
516         * method performs a linear search of this node's children for {@code child}
517         * and is {@code O(n)} where n is the number of children.
518         *
519         * @param child the child node
520         * @return  the child of this node that immediately precedes the {@code child},
521         *          or {@code null} if the given {@code node} is the first node.
522         * @throws NullPointerException if the given {@code child} is {@code null}
523         */
524        default Optional<T> childBefore(final Tree<?, ?> child) {
525                requireNonNull(child);
526
527                final int index = indexOf(child);
528                if (index == -1) {
529                        throw new IllegalArgumentException("The given node is not a child.");
530                }
531
532                return index > 0
533                        ? Optional.of(childAt(index - 1))
534                        : Optional.empty();
535        }
536
537        /**
538         * Return the node that follows {@code this} node in a pre-order traversal
539         * of {@code this} tree node. Return {@code Optional.empty()} if this node
540         * is the last node of the traversal. This is an inefficient way to traverse
541         * the entire tree use an iterator instead.
542         *
543         * @see #preorderIterator
544         * @return the node that follows this node in a pre-order traversal, or
545         *        {@code Optional.empty()} if this node is last
546         */
547        default Optional<T> nextNode() {
548                Optional<T> next = Optional.empty();
549
550                if (childCount() == 0) {
551                        T node = Trees.self(this);
552                        while (node != null && !(next = node.nextSibling()).isPresent()) {
553                                node = node.parent().orElse(null);
554                        }
555                } else {
556                        next = Optional.of(childAt(0));
557                }
558
559                return next;
560        }
561
562        /**
563         * Return the node that precedes this node in a pre-order traversal of
564         * {@code this} tree node. Returns {@code Optional.empty()} if this node is
565         * the first node of the traversal, the root of the tree. This is an
566         * inefficient way to traverse the entire tree; use an iterator instead.
567         *
568         * @see #preorderIterator
569         * @return the node that precedes this node in a pre-order traversal, or
570         *         {@code Optional.empty()} if this node is the first
571         */
572        default Optional<T> previousNode() {
573                Optional<T> node = Optional.empty();
574
575                if (parent().isPresent()) {
576                        final Optional<T> prev = previousSibling();
577                        if (prev.isPresent()) {
578                                node = prev.get().childCount() == 0
579                                        ? prev
580                                        : prev.map(Tree<V, T>::lastLeaf);
581                        } else {
582                                node = parent();
583                        }
584                }
585
586                return node;
587        }
588
589        /* *************************************************************************
590         * Sibling query operations
591         **************************************************************************/
592
593        /**
594         * Test if the given {@code node} is a sibling of {@code this} node.
595         *
596         * @param node node to test as sibling of this node
597         * @return {@code true} if the {@code node} is a sibling of {@code this}
598         *         node
599         * @throws NullPointerException if the given {@code node} is {@code null}
600         */
601        default boolean isSibling(final Tree<?, ?> node) {
602                return identical(requireNonNull(node)) ||
603                        parent().equals(node.parent());
604        }
605
606        /**
607         * Return the number of siblings of {@code this} node. A node is its own
608         * sibling (if it has no parent or no siblings, this method returns
609         * {@code 1}).
610         *
611         * @return the number of siblings of {@code this} node
612         */
613        default int siblingCount() {
614                return parent().map(Tree<V, T>::childCount).orElse(1);
615        }
616
617        /**
618         * Return the next sibling of {@code this} node in the parent's children
619         * array, or {@code null} if {@code this} node has no parent or it is the
620         * last child of the paren. This method performs a linear search that is
621         * {@code O(n)} where n is the number of children; to traverse the entire
622         * array, use the iterator of the parent instead.
623         *
624         * @see #childStream()
625         * @return the sibling of {@code this} node that immediately follows
626         *         {@code this} node
627         */
628        default Optional<T> nextSibling() {
629                return parent().flatMap(p -> p.childAfter(Trees.<V, T>self(this)));
630        }
631
632        /**
633         * Return the previous sibling of {@code this} node in the parent's children
634         * list, or {@code Optional.empty()} if this node has no parent or is the
635         * parent's first child. This method performs a linear search that is O(n)
636         * where n is the number of children.
637         *
638         * @return the sibling of {@code this} node that immediately precedes this
639         *         node
640         */
641        default Optional<T> previousSibling() {
642                return parent().flatMap(p -> p.childBefore(Trees.<V, T>self(this)));
643        }
644
645
646        /* *************************************************************************
647         * Leaf query operations
648         **************************************************************************/
649
650        /**
651         * Return {@code true} if {@code this} node has no children.
652         *
653         * @return {@code true} if {@code this} node has no children, {@code false}
654         *         otherwise
655         */
656        default boolean isLeaf() {
657                return childCount() == 0;
658        }
659
660        /**
661         * Return the first leaf that is a descendant of {@code this} node; either
662         * this node or its first child's first leaf. {@code this} node is returned
663         * if it is a leaf.
664         *
665         * @see #isLeaf
666         * @see  #isDescendant
667         * @return the first leaf in the subtree rooted at this node
668         */
669        default T firstLeaf() {
670                T leaf = Trees.self(this);
671                while (!leaf.isLeaf()) {
672                        leaf = leaf.firstChild().orElseThrow(AssertionError::new);
673                }
674
675                return leaf;
676        }
677
678        /**
679         * Return the last leaf that is a descendant of this node; either
680         * {@code this} node or its last child's last leaf. Returns {@code this}
681         * node if it is a leaf.
682         *
683         * @see #isLeaf
684         * @see #isDescendant
685         * @return the last leaf in this subtree
686         */
687        default T lastLeaf() {
688                T leaf = Trees.self(this);
689                while (!leaf.isLeaf()) {
690                        leaf = leaf.lastChild().orElseThrow(AssertionError::new);
691                }
692
693                return leaf;
694        }
695
696        /**
697         * Returns the leaf after {@code this} node or {@code Optional.empty()} if
698         * this node is the last leaf in the tree.
699         * <p>
700         * In order to determine the next node, this method first performs a linear
701         * search in the parent's child-list in order to find the current node.
702         * <p>
703         * That implementation makes the operation suitable for short traversals
704         * from a known position. But to traverse all of the leaves in the tree, you
705         * should use {@link #depthFirstIterator()} to iterator the nodes in the
706         * tree and use {@link #isLeaf()} on each node to determine which are leaves.
707         *
708         * @see #depthFirstIterator
709         * @see #isLeaf
710         * @return return the next leaf past this node
711         */
712        default Optional<T> nextLeaf() {
713                return nextSibling()
714                        .map(s -> Optional.of(s.firstLeaf()))
715                        .orElseGet(() -> parent().flatMap(Tree<V, T>::nextLeaf));
716        }
717
718        /**
719         * Return the leaf before {@code this} node or {@code null} if {@code this}
720         * node is the first leaf in the tree.
721         * <p>
722         * In order to determine the previous node, this method first performs a
723         * linear search in the parent's child-list in order to find the current
724         * node.
725         * <p>
726         * That implementation makes the operation suitable for short traversals
727         * from a known position. But to traverse all of the leaves in the tree, you
728         * should use {@link #depthFirstIterator()} to iterate the nodes in the tree
729         * and use {@link #isLeaf()} on each node to determine which are leaves.
730         *
731         * @see #depthFirstIterator
732         * @see #isLeaf
733         * @return returns the leaf before {@code this} node
734         */
735        default Optional<T> previousLeaf() {
736                return previousSibling()
737                        .map(s -> Optional.of(s.lastLeaf()))
738                        .orElseGet(() -> parent().flatMap(Tree<V, T>::previousLeaf));
739        }
740
741        /**
742         * Returns the total number of leaves that are descendants of this node.
743         * If this node is a leaf, returns {@code 1}. This method is {@code O(n)},
744         * where n is the number of descendants of {@code this} node.
745         *
746         * @see #isLeaf()
747         * @return the number of leaves beneath this node
748         */
749        default int leafCount() {
750                return (int)breadthFirstStream()
751                        .filter(Tree<V, T>::isLeaf)
752                        .count();
753        }
754
755        /* *************************************************************************
756         * Tree traversing.
757         **************************************************************************/
758
759        /**
760         * Return an iterator that traverses the subtree rooted at {@code this}
761         * node in breadth-first order. The first node returned by the iterator is
762         * {@code this} node.
763         * <p>
764         * Modifying the tree by inserting, removing, or moving a node invalidates
765         * any iterator created before the modification.
766         *
767         * @see #depthFirstIterator
768         * @return an iterator for traversing the tree in breadth-first order
769         */
770        default Iterator<T> breadthFirstIterator() {
771                return new TreeNodeBreadthFirstIterator<>(Trees.<V, T>self(this));
772        }
773
774        /**
775         * Return an iterator that traverses the subtree rooted at {@code this}.
776         * The first node returned by the iterator is {@code this} node.
777         * <p>
778         * Modifying the tree by inserting, removing, or moving a node invalidates
779         * any iterator created before the modification.
780         *
781         * @see #breadthFirstIterator
782         * @return an iterator for traversing the tree in breadth-first order
783         */
784        @Override
785        default Iterator<T> iterator() {
786                return breadthFirstIterator();
787        }
788
789        /**
790         * Return a stream that traverses the subtree rooted at {@code this} node in
791         * breadth-first order. The first node returned by the stream is
792         * {@code this} node.
793         *
794         * @see #depthFirstIterator
795         * @see #stream()
796         * @return a stream for traversing the tree in breadth-first order
797         */
798        default Stream<T> breadthFirstStream() {
799                return StreamSupport
800                        .stream(spliteratorUnknownSize(breadthFirstIterator(), 0), false);
801        }
802
803        /**
804         * Return a stream that traverses the subtree rooted at {@code this} node in
805         * breadth-first order. The first node returned by the stream is
806         * {@code this} node.
807         *
808         * @see #breadthFirstStream
809         * @return a stream for traversing the tree in breadth-first order
810         */
811        default Stream<T> stream() {
812                return breadthFirstStream();
813        }
814
815        /**
816         * Return an iterator that traverses the subtree rooted at {@code this} node
817         * in pre-order. The first node returned by the iterator is {@code this}
818         * node.
819         * <p>
820         * Modifying the tree by inserting, removing, or moving a node invalidates
821         * any iterator created before the modification.
822         *
823         * @see #postorderIterator
824         * @return an iterator for traversing the tree in pre-order
825         */
826        default Iterator<T> preorderIterator() {
827                return new TreeNodePreorderIterator<>(Trees.<V, T>self(this));
828        }
829
830        /**
831         * Return a stream that traverses the subtree rooted at {@code this} node
832         * in pre-order. The first node returned by the stream is {@code this} node.
833         * <p>
834         * Modifying the tree by inserting, removing, or moving a node invalidates
835         * any iterator created before the modification.
836         *
837         * @see #preorderIterator
838         * @return a stream for traversing the tree in pre-order
839         */
840        default Stream<T> preorderStream() {
841                return StreamSupport
842                        .stream(spliteratorUnknownSize(preorderIterator(), 0), false);
843        }
844
845        /**
846         * Return an iterator that traverses the subtree rooted at {@code this}
847         * node in post-order. The first node returned by the iterator is the
848         * leftmost leaf.  This is the same as a depth-first traversal.
849         *
850         * @see #depthFirstIterator
851         * @see #preorderIterator
852         * @return an iterator for traversing the tree in post-order
853         */
854        default Iterator<T> postorderIterator() {
855                return new TreeNodePostorderIterator<>(Trees.<V, T>self(this));
856        }
857
858        /**
859         * Return a stream that traverses the subtree rooted at {@code this} node in
860         * post-order. The first node returned by the iterator is the leftmost leaf.
861         * This is the same as a depth-first traversal.
862         *
863         * @see #depthFirstIterator
864         * @see #preorderIterator
865         * @return a stream for traversing the tree in post-order
866         */
867        default Stream<T> postorderStream() {
868                return StreamSupport
869                        .stream(spliteratorUnknownSize(postorderIterator(), 0), false);
870        }
871
872        /**
873         * Return an iterator that traverses the subtree rooted at {@code this} node
874         * in depth-first order. The first node returned by the iterator is the
875         * leftmost leaf. This is the same as a postorder traversal.
876         * <p>
877         * Modifying the tree by inserting, removing, or moving a node invalidates
878         * any iterator created before the modification.
879         *
880         * @see #breadthFirstIterator
881         * @see #postorderIterator
882         * @return an iterator for traversing the tree in depth-first order
883         */
884        default Iterator<T> depthFirstIterator() {
885                return postorderIterator();
886        }
887
888        /**
889         * Return a stream that traverses the subtree rooted at {@code this} node in
890         * depth-first. The first node returned by the iterator is the leftmost leaf.
891         * This is the same as a post-order traversal.
892         *
893         * @see #depthFirstIterator
894         * @see #preorderIterator
895         * @return a stream for traversing the tree in post-order
896         */
897        default Stream<T> depthFirstStream() {
898                return postorderStream();
899        }
900
901        /**
902         * Return an iterator that follows the path from {@code ancestor} to
903         * {@code this} node. The iterator return {@code ancestor} as first element,
904         * The creation of the iterator is O(m), where m is the number of nodes
905         * between {@code this} node and the {@code ancestor}, inclusive.
906         * <p>
907         * Modifying the tree by inserting, removing, or moving a node invalidates
908         * any iterator created before the modification.
909         *
910         * @see #isAncestor
911         * @see #isDescendant
912         * @param ancestor the ancestor node
913         * @return an iterator for following the path from an ancestor of {@code this}
914         *         node to this one
915         * @throws IllegalArgumentException if the {@code ancestor} is not an
916         *         ancestor of this node
917         * @throws NullPointerException if the given {@code ancestor} is {@code null}
918         */
919        default Iterator<T> pathFromAncestorIterator(final Tree<?, ?> ancestor) {
920                return new TreeNodePathIterator<>(ancestor, Trees.<V, T>self(this));
921        }
922
923        /**
924         * Return the path of {@code this} child node from the root node. You will
925         * get {@code this} node, if you call {@link #childAtPath(Path)} on the
926         * root node of {@code this} node.
927         * <pre>{@code
928         * final Tree<?, ?> node = ...;
929         * final Tree<?, ?> root = node.getRoot();
930         * final int[] path = node.childPath();
931         * assert node == root.childAtPath(path);
932         * }</pre>
933         *
934         * @since 4.4
935         *
936         * @see #childAtPath(Path)
937         *
938         * @return the path of {@code this} child node from the root node.
939         */
940        default Path childPath() {
941                final Iterator<T> it = pathFromAncestorIterator(root());
942                final int[] path = new int[level()];
943
944                T tree = null;
945                int index = 0;
946                while (it.hasNext()) {
947                        final T child = it.next();
948                        if (tree != null) {
949                                path[index++] = tree.indexOf(child);
950                        }
951
952                        tree = child;
953                }
954
955                assert index == path.length;
956
957                return new Path(path);
958        }
959
960        /**
961         * Tests whether {@code this} node is the same as the {@code other} node.
962         * The default implementation returns the object identity,
963         * {@code this == other}, of the two objects, but other implementations may
964         * use different criteria for checking the <i>identity</i>.
965         *
966         * @param other the {@code other} node
967         * @return {@code true} if the {@code other} node is the same as {@code this}
968         *         node.
969         */
970        default boolean identical(final Tree<?, ?> other) {
971                return this == other;
972        }
973
974        /* *************************************************************************
975         * 'toString' methods
976         **************************************************************************/
977
978        /**
979         * Return a compact string representation of the given tree. The tree
980         * <pre>
981         *  mul
982         *  ├── div
983         *  │   ├── cos
984         *  │   │   └── 1.0
985         *  │   └── cos
986         *  │       └── π
987         *  └── sin
988         *      └── mul
989         *          ├── 1.0
990         *          └── z
991         *  </pre>
992         * is printed as
993         * <pre>
994         *  mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
995         * </pre>
996         *
997         * @since 4.3
998         *
999         * @see #toParenthesesString()
1000         * @see TreeFormatter#PARENTHESES
1001         *
1002         * @param mapper the {@code mapper} which converts the tree value to a string
1003         * @return the string representation of the given tree
1004         */
1005        default String toParenthesesString(final Function<? super V, String> mapper) {
1006                return TreeFormatter.PARENTHESES.format(this, mapper);
1007        }
1008
1009        /**
1010         * Return a compact string representation of the given tree. The tree
1011         * <pre>
1012         *  mul
1013         *  ├── div
1014         *  │   ├── cos
1015         *  │   │   └── 1.0
1016         *  │   └── cos
1017         *  │       └── π
1018         *  └── sin
1019         *      └── mul
1020         *          ├── 1.0
1021         *          └── z
1022         *  </pre>
1023         * is printed as
1024         * <pre>
1025         *  mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
1026         * </pre>
1027         *
1028         * @since 4.3
1029         *
1030         * @see #toParenthesesString(Function)
1031         * @see TreeFormatter#PARENTHESES
1032         *
1033         * @return the string representation of the given tree
1034         * @throws NullPointerException if the {@code mapper} is {@code null}
1035         */
1036        default String toParenthesesString() {
1037                return toParenthesesString(Objects::toString);
1038        }
1039
1040        /* *************************************************************************
1041         * Static helper methods.
1042         **************************************************************************/
1043
1044        /**
1045         * Calculates the hash code of the given tree.
1046         *
1047         * @param tree the tree where the hash is calculated from
1048         * @return the hash code of the tree
1049         * @throws NullPointerException if the given {@code tree} is {@code null}
1050         */
1051        static int hashCode(final Tree<?, ?> tree) {
1052                return tree != null
1053                        ? tree.breadthFirstStream()
1054                                .mapToInt(node -> 31*Objects.hashCode(node.value()) + 37)
1055                                .sum() + 17
1056                        : 0;
1057        }
1058
1059        /**
1060         * Checks if the two given trees has the same structure with the same values.
1061         *
1062         * @param a the first tree
1063         * @param b the second tree
1064         * @return {@code true} if the two given trees are structurally equals,
1065         *         {@code false} otherwise
1066         */
1067        static boolean equals(final Tree<?, ?> a, final Tree<?, ?> b) {
1068                return Trees.equals(a, b);
1069        }
1070
1071        /**
1072         * Return a string representation of the given tree, like the following
1073         * example.
1074         *
1075         * <pre>
1076         *  mul(div(cos(1.0), cos(π)), sin(mul(1.0, z)))
1077         * </pre>
1078         *
1079         * This method is intended to be used when override the
1080         * {@link Object#toString()} method.
1081         *
1082         * @param tree the input tree
1083         * @return the string representation of the given tree
1084         */
1085        static String toString(final Tree<?, ?> tree) {
1086                return tree.toParenthesesString();
1087        }
1088
1089
1090        /* *************************************************************************
1091         * Inner classes
1092         **************************************************************************/
1093
1094        /**
1095         * This class represents the path to child within a given tree. It allows to
1096         * point (and fetch) a tree child.
1097         *
1098         * @see Tree#childAtPath(Path)
1099         *
1100         * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
1101         * @version 4.4
1102         * @since 4.4
1103         */
1104        final class Path implements Serializable {
1105                private static final long serialVersionUID = 1L;
1106
1107                private final int[] _path;
1108
1109                private Path(final int[] path) {
1110                        _path = requireNonNull(path);
1111                }
1112
1113                /**
1114                 * Return the path length, which is the level of the child {@code this}
1115                 * path points to.
1116                 *
1117                 * @return the path length
1118                 */
1119                public int length() {
1120                        return _path.length;
1121                }
1122
1123                /**
1124                 * Return the child index at the given index (child level).
1125                 *
1126                 * @param index the path index
1127                 * @return the child index at the given child level
1128                 * @throws IndexOutOfBoundsException if the index is not with the range
1129                 *         {@code [0, length())}
1130                 */
1131                public int get(final int index) {
1132                        return _path[index];
1133                }
1134
1135                /**
1136                 * Return the path as {@code int[]} array.
1137                 *
1138                 * @return the path as {@code int[]} array
1139                 */
1140                public int[] toArray() {
1141                        return _path.clone();
1142                }
1143
1144                /**
1145                 * Appends the given {@code path} to {@code this} one.
1146                 *
1147                 * @param path the path to append
1148                 * @return a new {@code Path} with the given {@code path} appended
1149                 * @throws NullPointerException if the given {@code path} is {@code null}
1150                 */
1151                public Path append(final Path path) {
1152                        final int[] p = new int[length() + path.length()];
1153                        System.arraycopy(_path, 0, p, 0, length());
1154                        System.arraycopy(path._path, 0, p, length(), path.length());
1155                        return new Path(p);
1156                }
1157
1158                @Override
1159                public int hashCode() {
1160                        return Arrays.hashCode(_path);
1161                }
1162
1163                @Override
1164                public boolean equals(final Object obj) {
1165                        return obj == this ||
1166                                obj instanceof Path &&
1167                                Arrays.equals(_path, ((Path)obj)._path);
1168                }
1169
1170                @Override
1171                public String toString() {
1172                        return Arrays.toString(_path);
1173                }
1174
1175                /**
1176                 * Create a new path object from the given child indexes.
1177                 *
1178                 * @param path the child indexes
1179                 * @return a new tree path
1180                 * @throws IllegalArgumentException if one of the path elements is
1181                 *         smaller than zero
1182                 */
1183                public static Path of(final int... path) {
1184                        for (int i = 0; i < path.length; ++i) {
1185                                if (path[i] < 0) {
1186                                        throw new IllegalArgumentException(format(
1187                                                "Path element at position %d is smaller than zero: %d",
1188                                                i, path[i]
1189                                        ));
1190                                }
1191                        }
1192
1193                        return new Path(path.clone());
1194                }
1195        }
1196
1197}