diff --git a/iterator/etc/bst.png b/iterator/etc/bst.png new file mode 100644 index 000000000..52ce7013e Binary files /dev/null and b/iterator/etc/bst.png differ diff --git a/iterator/etc/iterator.ucls b/iterator/etc/iterator.ucls index 440f9a28b..d36dad95d 100644 --- a/iterator/etc/iterator.ucls +++ b/iterator/etc/iterator.ucls @@ -1,7 +1,7 @@ - - - - - diff --git a/iterator/pom.xml b/iterator/pom.xml index 6581b8224..81a785dd1 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -48,5 +48,11 @@ junit-jupiter-params test + + org.junit.platform + junit-platform-runner + 1.2.0 + test + diff --git a/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/BstIterator.java b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/BstIterator.java new file mode 100644 index 000000000..b61482389 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/BstIterator.java @@ -0,0 +1,78 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.iterator.binarysearchtree; + +import com.iluwatar.iterator.interfaces.Iterator; +import java.util.ArrayDeque; + +/** + * This BstIterator iterates IN order. For example, given a BST with Integer values, + * expect to retrieve TreeNodes according to the Integer's natural ordering (1, 2, 3...) + * @param This Iterator has been implemented with generic typing to allow traversal of TreeNodes of various types + */ +public class BstIterator implements Iterator { + + private ArrayDeque> pathStack; + + public BstIterator(TreeNode root) { + pathStack = new ArrayDeque<>(); + pushPathToNextSmallest(root); + } + + /** + * This BstIterator manages to use O(h) extra space, where h is the height of the tree + * It achieves this by maintaining a stack of the nodes to handle (pushing all left nodes first), + * before handling self or right node + * @param node TreeNode that acts as root of the subtree we're interested in. + */ + private void pushPathToNextSmallest(TreeNode node) { + while (node != null) { + pathStack.push(node); + node = node.getLeft(); + } + } + + /** + * @return true if this iterator has a "next" element + */ + @Override + public boolean hasNext() { + return !pathStack.isEmpty(); + } + + /** + * + * @return TreeNode next. The next element according to our in-order traversal of the given BST + * @throws IllegalStateException if this iterator does not have a next element + */ + @Override + public TreeNode next() throws IllegalStateException { + if (pathStack.isEmpty()) { + throw new IllegalStateException(); + } + TreeNode next = pathStack.pop(); + pushPathToNextSmallest(next.getRight()); + return next; + } + +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/README.md b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/README.md new file mode 100644 index 000000000..766c4e1c5 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/README.md @@ -0,0 +1,86 @@ +# BSTIterator +An implementation of the Iterator design pattern, for the Binary Search Tree +data structure. A great explanation of BSTs can be found in this [video tutorial](https://www.youtube.com/watch?v=i_Q0v_Ct5lY). + +### What it Does +This iterator assumes that the given binary search tree inserts nodes of smaller +value to the left, and nodes of larger value to the right of current node. Accordingly, +this iterator will return nodes according to "In Order" binary tree traversal. +This means that given a binary search tree like the following, the iterator would +return values in order: 1, 3, 4, 6, 7, 8, 10, 13, 14. + +![BST](../../../../../../../etc/bst.png "Binary Search Tree") + +### How It's Done +**The trivial solution** to a binary search tree iterator would be to construct a List (or similar +linear data structure) when you construct the BSTIterator. This would require traversing the entire +BST, adding each node value to your list as you go. The downside to the trivial solution is twofold. +You're front loading the work by requiring the BSTIterator's constructor to traverse the entire tree, +and you're taking up more memory by maintaining (worst case) every node in the tree in a separate +data structure. In Big O terms, here are the costs, where n is the number of nodes in the tree: +* Constructor Run Time: O(n) +* `next()` Run Time: O(1) +* `hasNext()` Run Time: O(1) +* Extra Space: O(n) + +**A better solution** is to maintain _only_ the path to the next smallest node. For instance, given +the BST above, when you first create your BSTIterator, instead of traversing the entire tree, you +would navigate to the next smallest node (in this case, 1), pushing nodes onto a stack along the way. +Your BSTIterator Constructor would look like: +``` +private ArrayDeque pathStack; + +public BSTIterator(TreeNode root) { + pathStack = new ArrayDeque<>(); + pushPathToNextSmallest(root); +} + +private void pushPathToNextSmallest(TreeNode node) { + while (node != null) { + pathStack.push(node); + node = node.getLeft(); + } +} +``` + +After the constructor is called our BST, your `pathStack` would look like this: + +1\ +3\ +8 + +This way, you're certain of what the next smallest node is because it lives on top of your path +stack. In order to maintain the integrity of this path stack, when you call `next()` and pop a +node off the stack, you must check to see if it has a right child. If it does, then you must follow the right +child's path to the next smallest node (pushing onto your path stack as you go). Given our above example, +calling `next()` on our BSTIterator twice would return node "3". Node "3" has a right child, indicating +a path to a node smaller than 3's parent. In this case, you would push node "6" onto the stack, +and node "4" onto the stack. `next()` would look like this: + +``` +public TreeNode next() throws IllegalStateException { + // If the user calls next() and hasNext() is false + if (pathStack.isEmpty()) { + throw new IllegalStateException(); + } + TreeNode next = pathStack.pop(); + // follow right child to next smallest node + pushPathToNextSmallest(next.getRight()); + return next; +} +``` + +**Key Concept:** The path to the smallest node of a given subtree is navigating straight to the +leftmost node of that subtree. + +In Big O terms, here are the costs for our improved solution, where h is the height of the tree: +* Constructor Run Time: O(h) +* `next()` Amortized Run Time: O(1) +* `hasNext()` Run Time: O(1) +* Extra Space: O(h) + +As you can see, this solution more evenly distributes the work. It yields the same amortized +runtime for `next()`, reduces the run time of the constructor, and uses less extra space. + + + \ No newline at end of file diff --git a/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/TreeNode.java b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/TreeNode.java new file mode 100644 index 000000000..ceffa6cf5 --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/binarysearchtree/TreeNode.java @@ -0,0 +1,66 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.binarysearchtree; + +/** + * This TreeNode class allows for a generically typed value. + * @param generically typed to accept various data types for the val property + */ +public class TreeNode { + + private T val; + private TreeNode left; + private TreeNode right; + + /** + * Creates a TreeNode with a given value, and null children + * @param val The value of the given node + */ + public TreeNode(T val) { + this.val = val; + this.left = null; + this.right = null; + } + + T getVal() { + return val; + } + + TreeNode getLeft() { + return left; + } + + void setLeft(TreeNode left) { + this.left = left; + } + + TreeNode getRight() { + return right; + } + + void setRight(TreeNode right) { + this.right = right; + } + + @Override + public String toString() { + return val.toString(); + } + +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/interfaces/Iterator.java b/iterator/src/main/java/com/iluwatar/iterator/interfaces/Iterator.java new file mode 100644 index 000000000..a71c2440e --- /dev/null +++ b/iterator/src/main/java/com/iluwatar/iterator/interfaces/Iterator.java @@ -0,0 +1,30 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.interfaces; + +/** + * Iterator interface to be implemented by iterators over various data structures + * @param generically typed for various objects + */ +public interface Iterator { + + boolean hasNext(); + + T next(); +} diff --git a/iterator/src/main/java/com/iluwatar/iterator/App.java b/iterator/src/main/java/com/iluwatar/iterator/list/App.java similarity index 93% rename from iterator/src/main/java/com/iluwatar/iterator/App.java rename to iterator/src/main/java/com/iluwatar/iterator/list/App.java index d283347cb..9796b4f6d 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/App.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/App.java @@ -20,8 +20,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; +import com.iluwatar.iterator.interfaces.Iterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +31,7 @@ import org.slf4j.LoggerFactory; * The Iterator pattern is a design pattern in which an iterator is used to traverse a container and * access the container's elements. The Iterator pattern decouples algorithms from containers. *

- * In this example the Iterator ({@link ItemIterator}) adds abstraction layer on top of a collection + * In this example the Iterator ({@link Iterator}) adds abstraction layer on top of a collection * ({@link TreasureChest}). This way the collection can change its internal implementation without * affecting its clients. * diff --git a/iterator/src/main/java/com/iluwatar/iterator/Item.java b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java similarity index 97% rename from iterator/src/main/java/com/iluwatar/iterator/Item.java rename to iterator/src/main/java/com/iluwatar/iterator/list/Item.java index 47bc11354..7f0f92d99 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/Item.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; /** * diff --git a/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/list/ItemIterator.java similarity index 97% rename from iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java rename to iterator/src/main/java/com/iluwatar/iterator/list/ItemIterator.java index 0eab2f075..d5024daf5 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/ItemIterator.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; /** * diff --git a/iterator/src/main/java/com/iluwatar/iterator/ItemType.java b/iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java similarity index 97% rename from iterator/src/main/java/com/iluwatar/iterator/ItemType.java rename to iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java index 4cf36926e..e36062681 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/ItemType.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/ItemType.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; /** * diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java similarity index 98% rename from iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java rename to iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java index 4b9959269..8428b2308 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; import java.util.ArrayList; import java.util.List; diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java similarity index 98% rename from iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java rename to iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java index 9d841259f..80f019880 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java @@ -20,7 +20,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; import java.util.List; diff --git a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java index f448a378e..a879df31e 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java @@ -1,39 +1,33 @@ /** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.iluwatar.iterator; -import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.platform.suite.api.SuiteDisplayName; +import org.junit.runner.RunWith; /** - * - * Application test - * + * Runs a test suite containing all tests within the com.iluwatar.iterator package */ +@RunWith(JUnitPlatform.class) +@SuiteDisplayName("Iterator Test Suite") +@SelectPackages("com.iluwatar.iterator") public class AppTest { - - @Test - public void test() { - String[] args = {}; - App.main(args); - } -} +} \ No newline at end of file diff --git a/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/BstIteratorTest.java b/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/BstIteratorTest.java new file mode 100644 index 000000000..09645edff --- /dev/null +++ b/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/BstIteratorTest.java @@ -0,0 +1,98 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.binarysearchtree; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.iluwatar.iterator.AppTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +@TestInstance(Lifecycle.PER_CLASS) +class BstIteratorTest extends AppTest { + + private TreeNode nonEmptyRoot; + private TreeNode emptyRoot; + + @BeforeAll + void createTrees() { + nonEmptyRoot = new TreeNode(Integer.valueOf(5)); + nonEmptyRoot.setLeft(new TreeNode(3)); + nonEmptyRoot.setRight(new TreeNode(7)); + nonEmptyRoot.getLeft().setLeft(new TreeNode(1)); + nonEmptyRoot.getLeft().setRight(new TreeNode(4)); + nonEmptyRoot.getRight().setLeft(new TreeNode(6)); + + emptyRoot = null; + } + + @Test + void nextWithEmptyTree() { + BstIterator iter = new BstIterator(emptyRoot); + assertThrows(IllegalStateException.class, iter::next, + "next() should throw an IllegalStateException if hasNext() is false."); + } + + @Test + void nextWithPopulatedTree() { + BstIterator iter = new BstIterator(nonEmptyRoot); + assertEquals(iter.next().getVal(), 1, "First Node is 1."); + assertEquals(iter.next().getVal(), 3, "Second Node is 3."); + assertEquals(iter.next().getVal(), 4, "Third Node is 4."); + assertEquals(iter.next().getVal(), 5, "Fourth Node is 5."); + assertEquals(iter.next().getVal(), 6, "Fifth Node is 6."); + assertEquals(iter.next().getVal(), 7, "Sixth Node is 7."); + } + + @Test + void hasNextWithEmptyTree() { + BstIterator iter = new BstIterator(emptyRoot); + assertFalse(iter.hasNext(), "hasNext() should return false for empty tree."); + } + + @Test + void hasNextWithPopulatedTree() { + BstIterator iter = new BstIterator(nonEmptyRoot); + assertTrue(iter.hasNext(), "hasNext() should return true for populated tree."); + } + + @Test + void nextAndHasNextAcrossEntirePopulatedTree() { + BstIterator iter = new BstIterator(nonEmptyRoot); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 1, "First Node is 1."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 3, "Second Node is 3."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 4, "Third Node is 4."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 5, "Fourth Node is 5."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 6, "Fifth Node is 6."); + assertTrue(iter.hasNext(), "Iterator hasNext() should be true."); + assertEquals(iter.next().getVal(), 7, "Sixth Node is 7."); + assertFalse(iter.hasNext(), "Iterator hasNext() should be false, end of tree."); + } + +} diff --git a/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/TreeNodeTest.java b/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/TreeNodeTest.java new file mode 100644 index 000000000..8dd2e694e --- /dev/null +++ b/iterator/src/test/java/com/iluwatar/iterator/binarysearchtree/TreeNodeTest.java @@ -0,0 +1,55 @@ +/** + * The MIT License Copyright (c) 2014-2016 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.iterator.binarysearchtree; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +/** + * Comprehensive tests for TreeNode POJO + * @param generically typed for TreeNode + */ +public class TreeNodeTest { + + @Test + void treeNodeGetters() { + TreeNode node = new TreeNode(1); + assertEquals(node.getVal(), 1); + assertNull(node.getLeft(), "Left child should be initialized as null."); + assertNull(node.getRight(), "Right child should be initialized as null."); + } + + @Test + void treeNodeSetters() { + TreeNode node = new TreeNode(3); + node.setLeft(new TreeNode(1)); + assertEquals(node.getLeft().getVal(), 1, "Left node has a value of 1."); + node.setRight(new TreeNode(5)); + assertEquals(node.getRight().getVal(), 5, "Right node has a value of 5"); + } + + @Test + void treeNodeToString() { + TreeNode node = new TreeNode(3); + assertEquals(node.toString(), "3", "node.toString() should return string value."); + } + +} diff --git a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java b/iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java similarity index 95% rename from iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java rename to iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java index 665666aa7..ebfdbe9f1 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/list/TreasureChestTest.java @@ -20,8 +20,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.iterator; +package com.iluwatar.iterator.list; +import com.iluwatar.iterator.list.Item; +import com.iluwatar.iterator.list.ItemIterator; +import com.iluwatar.iterator.list.ItemType; +import com.iluwatar.iterator.list.TreasureChest; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource;