Note that there are some explanatory texts on larger screens.

plurals
  1. POWhen reading from a Scanner in a loop, it goes into an infinite loop
    primarykey
    data
    text
    <p>Two problems here. When I try to traverse this home-grown binary tree using a "recursive iterator" (an iterator that traverses the tree recursively, puts the elements into a queue, and then removes the elements from the front of the queue). The iterator tends to iterate backwards (greatest to least) instead of inorder (least to greatest). Also, when I try to read user input from a <code>Scanner</code> using <code>nextInt()</code>, the program goes into an infinite loop. I'm trying to catch the <code>InputMismatchException</code> when the user inputs an invalid number.<br> In the below code segment, I'm catching the InputMismatchException when the user doesn't input a number so that the program continues normally.<br> Testing file:</p> <pre><code>package assignments.unit9; import java.util.*; import static java.lang.System.*; import java.io.*; public class BinaryTreeTest { private static BinaryTree&lt;Item&gt; tree; static Scanner user; public static void main(String... args) { user = new Scanner(System.in); int choice; do { out.println("1. Read data from disk"); out.println("2. Print the tree in order"); out.println("3. Search the tree"); out.println("4. Delete from the tree"); out.println("5. Count the nodes in the tree"); out.print("0. Quit\n&gt;"); try { choice = user.nextInt(); } catch(InputMismatchException e) { choice = -1; } switch(choice) { case 0: exit(0); case 1: try { readFromDisk(); } catch(FileNotFoundException e) { err.println("Sorry, but the file could not be opened: " + e.getMessage()); } break; case 2: if(tree == null) { err.println("Must read file first"); break; } printTree(); break; case 3: if(tree == null) { err.println("Must read file first"); break; } searchTree(); break; case 4: if(tree == null) { err.println("Must read file first"); break; } // deleteFromTree(); break; case 5: if(tree == null) { err.println("Must read file first"); break; } countNodes(); break; default: err.println("Invalid choice. The available choices are:"); break; } } while(choice != 0); } public static void readFromDisk() throws FileNotFoundException { Scanner file = new Scanner(new File("file20.txt")); tree = new BinaryTree&lt;Item&gt;(); if(file.hasNextInt()) file.nextInt(); //skip the first integer while(file.hasNextInt()) { tree.add(new Item(file.nextInt(), file.nextInt())); } } public static void printTree() { tree.inorder(); } public static void searchTree() { out.println("Enter ID value to search for (-1 to return)"); int search; Item searched; while((search = user.nextInt()) != -1) { out.println(searched = tree.find(new Item(search, 0))); if(searched == null) out.println("\b\b\b\b\bNo such part in stock"); } } public static void countNodes() { out.println(tree.countNodes()); } } </code></pre> <p>Here, in the BinaryTree class, I try to traverse it recursively (see iterator() and asQueue()): </p> <pre><code>package assignments.unit9; import java.util.*; public class BinaryTree&lt;E extends Comparable&lt;E&gt;&gt; implements Iterable&lt;E&gt; { private TreeNode&lt;E&gt; root; public void add(E value) { if(root == null) { root = new TreeNode&lt;E&gt;(value); } else { TreeNode&lt;E&gt; temp = root, upFrom = null; boolean goesOnLeft = false; while(true) { if(temp == null) { if(goesOnLeft) upFrom.setLeft(new TreeNode&lt;E&gt;(value)); else upFrom.setRight(new TreeNode&lt;E&gt;(value)); break; } else if(temp.getValue().compareTo(value) &lt; 0) //goes on left { upFrom = temp; temp = upFrom.getLeft(); goesOnLeft = true; continue; } else //goes on right { upFrom = temp; temp = upFrom.getRight(); goesOnLeft = false; continue; } } } } public void inorder() { try { inorder(root); } catch(StackOverflowError e) { System.err.println("Increase stack size to print remaining elements"); } } private void inorder(TreeNode&lt;E&gt; t) { if(t == null) return; inorder(t.getLeft()); System.out.println(t.getValue()); inorder(t.getRight()); } private ArrayDeque&lt;E&gt; asQueue(TreeNode&lt;E&gt; t, ArrayDeque&lt;E&gt; toAdd) { try { if(toAdd == null) toAdd = new ArrayDeque&amp;lt;E&gt;(); if(t == null) return toAdd; asQueue(t.getLeft(), toAdd); toAdd.addLast(t.getValue()); asQueue(t.getRight(), toAdd); ret: return toAdd; } catch(StackOverflowError e) { throw new InternalError(); } } public Iterator&lt;E&gt; iterator() { return new Iterator&lt;E&gt;() { private ArrayDeque&lt;E&gt; d = asQueue(root, null); public E next() { return d.pop(); } public boolean hasNext() { return !d.isEmpty(); } public void remove() { throw new UnsupportedOperationException(); } }; } public int countNodes() { int toReturn = 0; for(E elem : this) ++toReturn; return toReturn; } public E find(E toFind) { for(E elem : this) { if(elem.equals(toFind)) return elem; } return null; } } </code></pre> <p>TreeNode class: </p> <pre><code>package assignments.unit9; import java.util.Objects; public class TreeNode&lt;T&gt; { private T value; private TreeNode&lt;T&gt; left, right; /** * Constructs a new TreeNode value with the left and right pointers {@code null}. * * @param value the item to be referenced * * @throws NullPointerException if {@code value} is {@code null}. */ public TreeNode(T value) { this.value = Objects.requireNonNull(value); } /** * Constructs a new TreeNode value with the specified left and right pointers. * * @param value the item to be referenced * @param left the TreeNode value to the left. * @param right the TreeNode value to the right. * * @throws NullPointerException if {@code value} is {@code null}. */ public TreeNode(T value, TreeNode&lt;T&gt; left, TreeNode&lt;T&gt; right) { this.value = Objects.requireNonNull(value); this.left = left; this.right = right; } public T getValue() { return value; } public TreeNode&lt;T&gt; getLeft() { return left; } public TreeNode&lt;T&gt; getRight() { return right; } public void setValue(T value) { this.value = Objects.requireNonNull(value); } public void setLeft(TreeNode&lt;T&gt; left) { this.left = left; } public void setRight(TreeNode&lt;T&gt; right) { this.right = right; } } </code></pre> <p>Data type (Item): </p> <pre><code>package assignments.unit9; import java.util.*; public class Item implements Comparable&lt;Item&gt; { private int myID; private int myInv; //Comparators public static class IDComparator implements Comparator&lt;Item&gt; { public int compare(Item i1, Item i2) { return i1.getID() - i2.getID(); } @Override public boolean equals(Object obj) { return obj instanceof IDComparator; } } public static class InvComparator implements Comparator&lt;Item&gt; { public int compare(Item i1, Item i2) { return i1.getInv() - i2.getInv(); } @Override public boolean equals(Object obj) { return obj instanceof InvComparator; } } public Item(int id, int inv) { myID = id; myInv = inv; } public int getID() { return myID; } public int getInv() { return myInv; } public int compareTo(Item i) { if(i == null) throw new NullPointerException(); return this.myID - i.myID; } @Override public boolean equals(Object otherObject) { Item i; try { i = (Item) otherObject; return myID == i.myID; } catch(ClassCastException ex) { return false; } } public String toString() { return "ID: " + myID + "\tInventory number: " + myInv + "\n"; } @Override public int hashCode() { return Objects.hash(myID, myInv); } } </code></pre> <p>And here's the input file. Sorry if that's a lot:</p> <pre><code>20 196 60 18618 64 2370 65 18410 56 18465 27 19967 45 17911 96 184 14 18871 69 14088 92 18061 3 206 31 13066 8 12705 14 15917 51 15814 60 15320 82 8303 90 7282 73 12328 63 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload