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}