0

这里有两个问题。当我尝试使用“递归迭代器”(递归遍历树,将元素放入队列,然后从队列前面删除元素的迭代器)遍历这棵本土二叉树时。迭代器倾向于向后迭代(从最大到最小)而不是按顺序(从最小到最大)迭代。此外,当我尝试从Scannerusing读取用户输入时nextInt(),程序进入无限循环。我试图捕捉InputMismatchException用户输入无效号码的时间。
在下面的代码段中,当用户没有输入数字以便程序正常继续时,我捕获了 InputMismatchException。
测试文件:

package assignments.unit9;
import java.util.*;
import static java.lang.System.*;
import java.io.*;
public class BinaryTreeTest
{
    private static BinaryTree<Item> 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>");
            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<Item>();
        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());
    }
}

在这里,在 BinaryTree 类中,我尝试递归遍历它(参见 iterator() 和 asQueue()):

package assignments.unit9;
import java.util.*;
public class BinaryTree<E extends Comparable<E>> implements Iterable<E>
{
    private TreeNode<E> root;

    public void add(E value)
    {
        if(root == null)
        {
            root = new TreeNode<E>(value);
        }
        else
        {
            TreeNode<E> temp = root, upFrom = null;
            boolean goesOnLeft = false;
            while(true)
            {
                if(temp == null)
                {
                    if(goesOnLeft)
                        upFrom.setLeft(new TreeNode<E>(value));
                    else
                        upFrom.setRight(new TreeNode<E>(value));
                    break;
                }
                else if(temp.getValue().compareTo(value) < 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<E> t)
    {
        if(t == null)
            return;
        inorder(t.getLeft());
        System.out.println(t.getValue());
        inorder(t.getRight());
    }

    private ArrayDeque<E> asQueue(TreeNode<E> t, ArrayDeque<E> toAdd)
    {
        try
        {
            if(toAdd == null)
                toAdd = new ArrayDeque&lt;E>();
            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<E> iterator()
    {
        return new Iterator<E>()
        {
            private ArrayDeque<E> 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;
    }
}

树节点类:

package assignments.unit9;
import java.util.Objects;
public class TreeNode<T>
{
    private T value;
    private TreeNode<T> 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<T> left, TreeNode<T> right)
    {
        this.value = Objects.requireNonNull(value);
        this.left = left;
        this.right = right;
    }

    public T getValue()
    {
        return value;
    }

    public TreeNode<T> getLeft()
    {
        return left;
    }

    public TreeNode<T> getRight()
    {
        return right;
    }

    public void setValue(T value)
    {
        this.value = Objects.requireNonNull(value);
    }

    public void setLeft(TreeNode<T> left)
    {
        this.left = left;
    }

    public void setRight(TreeNode<T> right)
    {
        this.right = right;
    }
}

数据类型(项目):

package assignments.unit9;
import java.util.*;
public class Item implements Comparable<Item>
{

    private int myID;
    private int myInv;

    //Comparators
    public static class IDComparator implements Comparator<Item>
    {
        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<Item>
    {
        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);
    }
}

这是输入文件。对不起,如果这很多:

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
4

2 回答 2

1

您的打印输出功能以相反的顺序打印节点,因为这是您存储它们的方式;您的二叉树在左侧而不是右侧具有较大的值,因为您的“添加”函数中有一个“>”而不是“<”。改变它,它们会增加而不是减少。

我仍然看不到你得到一个无限循环的条件,我自己也没有。将程序放入调试器并跟踪它的去向,直到你弄明白为止。老实说,我认为我在这个问题上已经做的够多了(我没有 Java 7,必须将它回填到 Java 6 才能运行它),我正在继续。

于 2013-03-12T11:07:35.137 回答
0

好的,问题解决了。问题是,<当我需要 a 时我输入了 a >,所以我最终得到了左侧较大的值和右侧较小的值,所以我的inorder遍历是向后的。其次,捕获导致的无限循环InputMismatchException是类中的一个错误Scanner

  1. in.nextInt()程序启动,启动在try块 中调用的循环。
  2. 当用户输入一个非数字时,扫描器会抛出一个InputMismatchException,这会将流量转移到 catch块,该块设置choice为 -1,这会导致显示无效的文本块。
  3. 但奇怪的是,在下一次迭代中,当nextInt()被调用时,它立即抛出异常而不是获取输入,如果在 catch 块中添加了 print 语句就可以看出这一点。感谢所有帮助我的人。
于 2013-03-13T01:37:14.097 回答