Merge pull request #779 from mitchellirvin/bst-iterator
#778: Binary Search Tree Iterator
This commit is contained in:
commit
038befea26
BIN
iterator/etc/bst.jpg
Normal file
BIN
iterator/etc/bst.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
|
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
|
||||||
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
|
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
|
||||||
<class id="1" language="java" name="com.iluwatar.iterator.TreasureChest" project="iterator"
|
<class id="1" language="java" name="com.iluwatar.iterator.list.TreasureChest" project="iterator"
|
||||||
file="/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="124" width="195" x="1" y="237"/>
|
<position height="124" width="195" x="1" y="237"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</class>
|
</class>
|
||||||
<class id="2" language="java" name="com.iluwatar.iterator.Item" project="iterator"
|
<class id="2" language="java" name="com.iluwatar.iterator.list.Item" project="iterator"
|
||||||
file="/iterator/src/main/java/com/iluwatar/iterator/Item.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/iterator/src/main/java/com/iluwatar/iterator/Item.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="160" width="157" x="195" y="401"/>
|
<position height="160" width="157" x="195" y="401"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</class>
|
</class>
|
||||||
<enumeration id="3" language="java" name="com.iluwatar.iterator.ItemType" project="iterator"
|
<enumeration id="3" language="java" name="com.iluwatar.iterator.list.ItemType" project="iterator"
|
||||||
file="/iterator/src/main/java/com/iluwatar/iterator/ItemType.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/iterator/src/main/java/com/iluwatar/iterator/ItemType.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="160" width="145" x="388" y="601"/>
|
<position height="160" width="145" x="388" y="601"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</enumeration>
|
</enumeration>
|
||||||
<interface id="4" language="java" name="com.iluwatar.iterator.ItemIterator" project="iterator"
|
<interface id="4" language="java" name="com.iluwatar.iterator.list.ItemIterator" project="iterator"
|
||||||
file="/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java" binary="false" corner="BOTTOM_RIGHT">
|
file="/iterator/src/main/java/com/iluwatar/iterator/ItemIterator.java" binary="false" corner="BOTTOM_RIGHT">
|
||||||
<position height="106" width="131" x="236" y="237"/>
|
<position height="106" width="131" x="236" y="237"/>
|
||||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||||
</display>
|
</display>
|
||||||
</interface>
|
</interface>
|
||||||
<class id="5" language="java" name="com.iluwatar.iterator.TreasureChestItemIterator" project="iterator"
|
<class id="5" language="java" name="com.iluwatar.iterator.list.TreasureChestItemIterator" project="iterator"
|
||||||
file="/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java" binary="false"
|
file="/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java" binary="false"
|
||||||
corner="BOTTOM_RIGHT">
|
corner="BOTTOM_RIGHT">
|
||||||
<position height="160" width="323" x="236" y="37"/>
|
<position height="160" width="323" x="236" y="37"/>
|
||||||
|
@ -1,76 +1,95 @@
|
|||||||
/**
|
/**
|
||||||
* The MIT License
|
* The MIT License Copyright (c) 2014-2016 Ilkka Seppälä
|
||||||
* Copyright (c) 2014-2016 Ilkka Seppälä
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
* in the Software without restriction, including without limitation the rights
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in all copies or
|
||||||
* all copies or substantial portions of the Software.
|
* substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* 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.
|
||||||
* 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;
|
||||||
|
|
||||||
|
import static com.iluwatar.iterator.list.ItemType.ANY;
|
||||||
|
import static com.iluwatar.iterator.list.ItemType.POTION;
|
||||||
|
import static com.iluwatar.iterator.list.ItemType.RING;
|
||||||
|
import static com.iluwatar.iterator.list.ItemType.WEAPON;
|
||||||
|
|
||||||
|
import com.iluwatar.iterator.bst.BstIterator;
|
||||||
|
import com.iluwatar.iterator.bst.TreeNode;
|
||||||
|
import com.iluwatar.iterator.list.Item;
|
||||||
|
import com.iluwatar.iterator.list.ItemType;
|
||||||
|
import com.iluwatar.iterator.list.TreasureChest;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The Iterator pattern is a design pattern in which an iterator is used to traverse a container and
|
* 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.
|
* access the container's elements. The Iterator pattern decouples algorithms from containers.
|
||||||
* <p>
|
* <p>
|
||||||
* 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
|
* ({@link TreasureChest}). This way the collection can change its internal implementation without
|
||||||
* affecting its clients.
|
* affecting its clients.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
|
private static final TreasureChest TREASURE_CHEST = new TreasureChest();
|
||||||
|
|
||||||
|
private static void demonstrateTreasureChestIteratorForType(ItemType itemType) {
|
||||||
|
LOGGER.info("------------------------");
|
||||||
|
LOGGER.info("Item Iterator for ItemType " + itemType + ": ");
|
||||||
|
Iterator<Item> itemIterator = TREASURE_CHEST.iterator(itemType);
|
||||||
|
while (itemIterator.hasNext()) {
|
||||||
|
LOGGER.info(itemIterator.next().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demonstrateBstIterator() {
|
||||||
|
LOGGER.info("------------------------");
|
||||||
|
LOGGER.info("BST Iterator: ");
|
||||||
|
TreeNode<Integer> root = buildIntegerBst();
|
||||||
|
BstIterator bstIterator = new BstIterator<>(root);
|
||||||
|
while (bstIterator.hasNext()) {
|
||||||
|
LOGGER.info("Next node: " + bstIterator.next().getVal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TreeNode<Integer> buildIntegerBst() {
|
||||||
|
TreeNode<Integer> root = new TreeNode<>(8);
|
||||||
|
|
||||||
|
root.insert(3);
|
||||||
|
root.insert(10);
|
||||||
|
root.insert(1);
|
||||||
|
root.insert(6);
|
||||||
|
root.insert(14);
|
||||||
|
root.insert(4);
|
||||||
|
root.insert(7);
|
||||||
|
root.insert(13);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
TreasureChest chest = new TreasureChest();
|
demonstrateTreasureChestIteratorForType(RING);
|
||||||
|
demonstrateTreasureChestIteratorForType(POTION);
|
||||||
|
demonstrateTreasureChestIteratorForType(WEAPON);
|
||||||
|
demonstrateTreasureChestIteratorForType(ANY);
|
||||||
|
|
||||||
ItemIterator ringIterator = chest.iterator(ItemType.RING);
|
demonstrateBstIterator();
|
||||||
while (ringIterator.hasNext()) {
|
|
||||||
LOGGER.info(ringIterator.next().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info("----------");
|
|
||||||
|
|
||||||
ItemIterator potionIterator = chest.iterator(ItemType.POTION);
|
|
||||||
while (potionIterator.hasNext()) {
|
|
||||||
LOGGER.info(potionIterator.next().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info("----------");
|
|
||||||
|
|
||||||
ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON);
|
|
||||||
while (weaponIterator.hasNext()) {
|
|
||||||
LOGGER.info(weaponIterator.next().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info("----------");
|
|
||||||
|
|
||||||
ItemIterator it = chest.iterator(ItemType.ANY);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
LOGGER.info(it.next().toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* ItemIterator interface.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ItemIterator {
|
|
||||||
|
|
||||||
boolean hasNext();
|
|
||||||
|
|
||||||
Item next();
|
|
||||||
}
|
|
30
iterator/src/main/java/com/iluwatar/iterator/Iterator.java
Normal file
30
iterator/src/main/java/com/iluwatar/iterator/Iterator.java
Normal file
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator interface to be implemented by iterators over various data structures
|
||||||
|
* @param <T> generically typed for various objects
|
||||||
|
*/
|
||||||
|
public interface Iterator<T> {
|
||||||
|
|
||||||
|
boolean hasNext();
|
||||||
|
|
||||||
|
T next();
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* 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.bst;
|
||||||
|
|
||||||
|
import com.iluwatar.iterator.Iterator;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An in-order implementation of a BST Iterator. For example, given a BST with Integer values,
|
||||||
|
* expect to retrieve TreeNodes according to the Integer's natural ordering (1, 2, 3...)
|
||||||
|
*
|
||||||
|
* @param <T> This Iterator has been implemented with generic typing to allow for TreeNodes of
|
||||||
|
* different value types
|
||||||
|
*/
|
||||||
|
public class BstIterator<T extends Comparable<T>> implements Iterator<TreeNode<T>> {
|
||||||
|
|
||||||
|
private ArrayDeque<TreeNode<T>> pathStack;
|
||||||
|
|
||||||
|
public BstIterator(TreeNode<T> 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<T> 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 NoSuchElementException if this iterator does not have a next element
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TreeNode<T> next() throws NoSuchElementException {
|
||||||
|
if (pathStack.isEmpty()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
TreeNode<T> next = pathStack.pop();
|
||||||
|
pushPathToNextSmallest(next.getRight());
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
iterator/src/main/java/com/iluwatar/iterator/bst/README.md
Normal file
86
iterator/src/main/java/com/iluwatar/iterator/bst/README.md
Normal file
@ -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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 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<TreeNode> 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
134
iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java
Normal file
134
iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* 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.bst;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TreeNode Class, representing one node in a Binary Search Tree. Allows for a generically typed
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @param <T> generically typed to accept various data types for the val property
|
||||||
|
*/
|
||||||
|
public class TreeNode<T extends Comparable<T>> {
|
||||||
|
|
||||||
|
private T val;
|
||||||
|
private TreeNode<T> left;
|
||||||
|
private TreeNode<T> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getVal() {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode<T> getLeft() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLeft(TreeNode<T> left) {
|
||||||
|
this.left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode<T> getRight() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRight(TreeNode<T> right) {
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts new TreeNode based on a given value into the subtree represented by self
|
||||||
|
*
|
||||||
|
* @param valToInsert The value to insert as a new TreeNode
|
||||||
|
*/
|
||||||
|
public void insert(T valToInsert) {
|
||||||
|
TreeNode<T> parent = getParentNodeOfValueToBeInserted(valToInsert);
|
||||||
|
parent.insertNewChild(valToInsert);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the Parent TreeNode for a given value to insert into the BST.
|
||||||
|
*
|
||||||
|
* @param valToInsert Value of the new TreeNode to be inserted
|
||||||
|
* @return Parent TreeNode of `valToInsert`
|
||||||
|
*/
|
||||||
|
private TreeNode<T> getParentNodeOfValueToBeInserted(T valToInsert) {
|
||||||
|
TreeNode<T> parent = null;
|
||||||
|
TreeNode<T> curr = this;
|
||||||
|
|
||||||
|
while (curr != null) {
|
||||||
|
parent = curr;
|
||||||
|
curr = curr.traverseOneLevelDown(valToInsert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns left or right child of self based on a value that would be inserted; maintaining the
|
||||||
|
* integrity of the BST.
|
||||||
|
*
|
||||||
|
* @param value The value of the TreeNode that would be inserted beneath self
|
||||||
|
* @return The child TreeNode of self which represents the subtree where `value` would be inserted
|
||||||
|
*/
|
||||||
|
private TreeNode<T> traverseOneLevelDown(T value) {
|
||||||
|
if (this.isGreaterThan(value)) {
|
||||||
|
return this.left;
|
||||||
|
}
|
||||||
|
return this.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new Child TreeNode of given value to self. WARNING: This method is destructive (will
|
||||||
|
* overwrite existing tree structure, if any), and should be called only by this class's insert()
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* @param valToInsert Value of the new TreeNode to be inserted
|
||||||
|
*/
|
||||||
|
private void insertNewChild(T valToInsert) {
|
||||||
|
if (this.isLessThanOrEqualTo(valToInsert)) {
|
||||||
|
this.setRight(new TreeNode<>(valToInsert));
|
||||||
|
} else {
|
||||||
|
this.setLeft(new TreeNode<>(valToInsert));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGreaterThan(T val) {
|
||||||
|
return this.val.compareTo(val) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLessThanOrEqualTo(T val) {
|
||||||
|
return this.val.compareTo(val) < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return val.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.iluwatar.iterator;
|
package com.iluwatar.iterator.list;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
@ -20,7 +20,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.iluwatar.iterator;
|
package com.iluwatar.iterator.list;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
@ -1,34 +1,31 @@
|
|||||||
/**
|
/**
|
||||||
* The MIT License
|
* The MIT License Copyright (c) 2014-2016 Ilkka Seppälä
|
||||||
* Copyright (c) 2014-2016 Ilkka Seppälä
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
* in the Software without restriction, including without limitation the rights
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in all copies or
|
||||||
* all copies or substantial portions of the Software.
|
* substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* 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.
|
||||||
* 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.Iterator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* TreasureChest, the collection class.
|
* TreasureChest, the collection class.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TreasureChest {
|
public class TreasureChest {
|
||||||
|
|
||||||
@ -51,7 +48,7 @@ public class TreasureChest {
|
|||||||
items.add(new Item(ItemType.WEAPON, "Dagger of poison"));
|
items.add(new Item(ItemType.WEAPON, "Dagger of poison"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemIterator iterator(ItemType itemType) {
|
public Iterator<Item> iterator(ItemType itemType) {
|
||||||
return new TreasureChestItemIterator(this, itemType);
|
return new TreasureChestItemIterator(this, itemType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,9 +56,7 @@ public class TreasureChest {
|
|||||||
* Get all items
|
* Get all items
|
||||||
*/
|
*/
|
||||||
public List<Item> getItems() {
|
public List<Item> getItems() {
|
||||||
List<Item> list = new ArrayList<>();
|
return new ArrayList<>(items);
|
||||||
list.addAll(items);
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,35 +1,32 @@
|
|||||||
/**
|
/**
|
||||||
* The MIT License
|
* The MIT License Copyright (c) 2014-2016 Ilkka Seppälä
|
||||||
* Copyright (c) 2014-2016 Ilkka Seppälä
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
* in the Software without restriction, including without limitation the rights
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in all copies or
|
||||||
* all copies or substantial portions of the Software.
|
* substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* 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.
|
||||||
* 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.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* TreasureChestItemIterator
|
* TreasureChestItemIterator
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TreasureChestItemIterator implements ItemIterator {
|
public class TreasureChestItemIterator implements Iterator<Item> {
|
||||||
|
|
||||||
private TreasureChest chest;
|
private TreasureChest chest;
|
||||||
private int idx;
|
private int idx;
|
||||||
@ -59,7 +56,6 @@ public class TreasureChestItemIterator implements ItemIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int findNextIdx() {
|
private int findNextIdx() {
|
||||||
|
|
||||||
List<Item> items = chest.getItems();
|
List<Item> items = chest.getItems();
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
int tempIdx = idx;
|
int tempIdx = idx;
|
@ -1,39 +1,34 @@
|
|||||||
/**
|
/**
|
||||||
* The MIT License
|
* The MIT License Copyright (c) 2014-2016 Ilkka Seppälä
|
||||||
* Copyright (c) 2014-2016 Ilkka Seppälä
|
* <p>
|
||||||
*
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
* in the Software without restriction, including without limitation the rights
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* 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:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
* <p>
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in all copies or
|
||||||
* all copies or substantial portions of the Software.
|
* substantial portions of the Software.
|
||||||
*
|
* <p>
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* 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.
|
||||||
* 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;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Application Test
|
||||||
* Application test
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class AppTest {
|
class AppTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
void testApp() {
|
||||||
String[] args = {};
|
String[] args = {};
|
||||||
App.main(args);
|
App.main(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* 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.bst;
|
||||||
|
|
||||||
|
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 org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
|
class BstIteratorTest {
|
||||||
|
|
||||||
|
private TreeNode<Integer> nonEmptyRoot;
|
||||||
|
private TreeNode<Integer> emptyRoot;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
void createTrees() {
|
||||||
|
nonEmptyRoot = new TreeNode<>(5);
|
||||||
|
nonEmptyRoot.insert(3);
|
||||||
|
nonEmptyRoot.insert(7);
|
||||||
|
nonEmptyRoot.insert(1);
|
||||||
|
nonEmptyRoot.insert(4);
|
||||||
|
nonEmptyRoot.insert(6);
|
||||||
|
|
||||||
|
emptyRoot = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nextForEmptyTree() {
|
||||||
|
BstIterator iter = new BstIterator<>(emptyRoot);
|
||||||
|
assertThrows(NoSuchElementException.class, iter::next,
|
||||||
|
"next() should throw an IllegalStateException if hasNext() is false.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nextOverEntirePopulatedTree() {
|
||||||
|
BstIterator iter = new BstIterator<>(nonEmptyRoot);
|
||||||
|
assertEquals(1, iter.next().getVal(), "First Node is 1.");
|
||||||
|
assertEquals(3, iter.next().getVal(), "Second Node is 3.");
|
||||||
|
assertEquals(4, iter.next().getVal(), "Third Node is 4.");
|
||||||
|
assertEquals(5, iter.next().getVal(), "Fourth Node is 5.");
|
||||||
|
assertEquals(6, iter.next().getVal(), "Fifth Node is 6.");
|
||||||
|
assertEquals(7, iter.next().getVal(), "Sixth Node is 7.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hasNextForEmptyTree() {
|
||||||
|
BstIterator iter = new BstIterator<>(emptyRoot);
|
||||||
|
assertFalse(iter.hasNext(), "hasNext() should return false for empty tree.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hasNextForPopulatedTree() {
|
||||||
|
BstIterator iter = new BstIterator<>(nonEmptyRoot);
|
||||||
|
assertTrue(iter.hasNext(), "hasNext() should return true for populated tree.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nextAndHasNextOverEntirePopulatedTree() {
|
||||||
|
BstIterator iter = new BstIterator<>(nonEmptyRoot);
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(1, iter.next().getVal(), "First Node is 1.");
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(3, iter.next().getVal(), "Second Node is 3.");
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(4, iter.next().getVal(), "Third Node is 4.");
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(5, iter.next().getVal(), "Fourth Node is 5.");
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(6, iter.next().getVal(), "Fifth Node is 6.");
|
||||||
|
assertTrue(iter.hasNext(), "Iterator hasNext() should be true.");
|
||||||
|
assertEquals(7, iter.next().getVal(), "Sixth Node is 7.");
|
||||||
|
assertFalse(iter.hasNext(), "Iterator hasNext() should be false, end of tree.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,37 +1,33 @@
|
|||||||
/**
|
/**
|
||||||
* The MIT License
|
* The MIT License Copyright (c) 2014-2016 Ilkka Seppälä
|
||||||
* Copyright (c) 2014-2016 Ilkka Seppälä
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
* in the Software without restriction, including without limitation the rights
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in all copies or
|
||||||
* all copies or substantial portions of the Software.
|
* substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* 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.
|
||||||
* 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 org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
import com.iluwatar.iterator.Iterator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date: 12/14/15 - 2:58 PM
|
* Date: 12/14/15 - 2:58 PM
|
||||||
*
|
*
|
||||||
@ -60,13 +56,14 @@ public class TreasureChestTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the expected item can be retrieved from the chest using the {@link ItemIterator}
|
* Test if the expected item can be retrieved from the chest using the {@link
|
||||||
|
* TreasureChestItemIterator}
|
||||||
*/
|
*/
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("dataProvider")
|
@MethodSource("dataProvider")
|
||||||
public void testIterator(Item expectedItem) {
|
public void testIterator(Item expectedItem) {
|
||||||
final TreasureChest chest = new TreasureChest();
|
final TreasureChest chest = new TreasureChest();
|
||||||
final ItemIterator iterator = chest.iterator(expectedItem.getType());
|
final Iterator<Item> iterator = chest.iterator(expectedItem.getType());
|
||||||
assertNotNull(iterator);
|
assertNotNull(iterator);
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
Loading…
x
Reference in New Issue
Block a user