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