作业帮助:数组很奇怪

时间:2018-10-31 11:04:19

标签: java arrays binary-search-tree

我正在研究二叉搜索树的分配,当我看到我在树上添加一个数字然后尝试检查它的前任/后继(将其放入)时,我正在测试我认为是成品的产品依次遍历然后检查索引之前/之后的索引),这只是...行不通。每当我尝试检查刚放在树中间的值的前任/后任时,它都会出现ArrayIndexOutOfBoundsException异常。重要说明是,仅使用inordertraverse(在代码中称为printInOrder)进行打印即可完美地工作。

由于打印了有序遍历,所以我可以认为我的树不是问题。唯一的另一件事是数组,对不对?我缺少明显的东西吗?

这是代码!

public class BST implements BSTInterface
{
//Variables/Fields
    private BNode root;

//Constructors
    public BST(int data)
    {
        root = new BNode(data);
    }

//Public Methods
    public boolean add(int data)
    {
        if(!contains(data))
        {
            root = addEntry(root, data);
            return true;
        }
        else
            return false;
    }

    public boolean contains(int data)
    {
        return containsNode(root, data);
    }

    public boolean remove(int data)
    {
        if(contains(data))
        {
            root = deleteNode(root, data);
            return true;
        }
        else
            return false;
    }

    public int[] toArray()
    {
        int[] output = new int[root.numNodes()];
        inorderTraverse(output, 0, root);
        return output;
    }

    public void printInOrder()
    {
        printIn(root);
    }

    public void printPreOrder()
    {
        printPre(root);
    }

    public void printPostOrder()
    {
        printPost(root);
    }


//Private methods/classes
    private class BNode
    {
        private int data;
        private BNode leftChild;
        private BNode rightChild;

        public BNode(int data)
        {
            this.data = data;
            leftChild = null;
            rightChild = null;
        }

        public int getData()
        {
            return data;
        }

        public void setData(int newData)
        {
            data = newData;
        }

        public BNode getLeftChild()
        {
            return leftChild;
        }

        public BNode getRightChild()
        {
            return rightChild;
        }

        public void setRightChild(BNode node)
        {
            rightChild = node;
        }

        public void setLeftChild(BNode node)
        {
            leftChild = node;
        }

        public int numNodes()
        {
            int leftNum = 0;
            int rightNum = 0;

            if(leftChild != null)
                leftNum = leftChild.numNodes();
            if(rightChild != null)
                rightNum = rightChild.numNodes();

            return 1+leftNum+rightNum;
        }


    }

    private BNode addEntry(BNode current, int data)
    {
        if(current == null)
            return new BNode(data);
        if(data < current.getData())
            current.setLeftChild(addEntry(current.getLeftChild(), data));
        else if(data > current.getData())
            current.setRightChild(addEntry(current.getRightChild(), data));
        return current;
    }

    private boolean containsNode(BNode current, int entry)
    {
        if(current == null)
            return false;
        if(entry == current.getData())
            return true;
        if(entry < current.getData())
            return containsNode(current.getLeftChild(), entry);
        else
            return containsNode(current.getRightChild(), entry);

    }

    private BNode deleteNode(BNode current, int data)
    {
        if(current == null)
            return null;
        if(data == current.getData())
        {
            if(current.getLeftChild() == null && current.getRightChild() == null) //No children
                return null;
            if(current.getRightChild() == null) //Only right child
                return current.getLeftChild();
            if(current.getLeftChild() == null) //Only left child
                return current.getRightChild();
            int smallestChild = findSmallest(current.getRightChild());
            current.setData(smallestChild);
            current.setRightChild(deleteNode(current.getRightChild(), smallestChild));
            return current;
        }
        if(data < current.getData())
        {
            current.setLeftChild(deleteNode(current.getLeftChild(), data));
            return current;
        }
        else
            current.setRightChild(deleteNode(current.getRightChild(), data));
            return current;

    }

    private int findSmallest(BNode root)
    {
        return root.getLeftChild() == null ? root.getData() : findSmallest(root.getLeftChild());
    }

    private void inorderTraverse(int[] array, int count, BNode node)
    {
        if(node != null)
        {
            inorderTraverse(array, count, node.getLeftChild());
            array[count] = node.getData();
            count++;
            inorderTraverse(array, count, node.getRightChild());
        }
    }

    private void printIn(BNode node)
    {
        if(node != null)
        {
            printIn(node.getLeftChild());
            System.out.print(node.getData() + " ");
            printIn(node.getRightChild());
        }
    }

    private void printPre(BNode node)
    {
        if(node != null)
        {
            System.out.print(node.getData() + " ");
            printPre(node.getLeftChild());
            printPre(node.getRightChild());
        }
    }

    private void printPost(BNode node)
    {
        if(node != null)
        {
            printPost(node.getLeftChild());
            printPost(node.getRightChild());
            System.out.print(node.getData() + " ");
        }
    }
}

以及驱动程序:

import java.util.Scanner;
public class BSTDemoReel
{
    public static void main(String[] args)
    {
        System.out.println("This search tree only handles integers! Thanks in advance!\n\n");
        Scanner keyboard = new Scanner(System.in);

        //Variables
        String input;
        String choice = "";
        int num;
        int index;
        boolean found;

        //Starting
        System.out.println("Please enter the initial sequence of values:\n");
        input = keyboard.nextLine();
        String[] splitInput = input.split(" ");
        int[] intInputArray = new int[splitInput.length];
        for(int count = 0; count < splitInput.length; count++)
        {
            intInputArray[count] = Integer.parseInt(splitInput[count]);
        }

        BST searchTree = new BST(intInputArray[0]);
        for(int count = 1; count < intInputArray.length; count++)
        {
            searchTree.add(intInputArray[count]);
        }

        System.out.print("Pre-order: ");
        searchTree.printPreOrder();
        System.out.println();

        System.out.print("In-order: ");
        searchTree.printInOrder();
        System.out.println();

        System.out.print("Post-order: ");
        searchTree.printPostOrder();
        System.out.println();

        //Menu
        while(!choice.equals("E"))
        {
            System.out.print("Command? ");
            choice = keyboard.next();
            choice = choice.toUpperCase();
            switch(choice)
            {
            case "I": num = keyboard.nextInt();
                    if(searchTree.contains(num))
                        System.out.println(num + " already exists. Please try again.");
                    else
                    {
                        searchTree.add(num);
                        System.out.print("In-order: ");
                        searchTree.printInOrder();
                        System.out.println();
                    }
                    break;
            case "D": num = keyboard.nextInt();
                    if(!searchTree.contains(num))
                        System.out.println(num + " does not exist. Please try again.");
                    else
                    {
                        searchTree.remove(num);
                        System.out.print("In-order: ");
                        searchTree.printInOrder();
                        System.out.println();
                    }
                    break;
            case "P": num = keyboard.nextInt();
                    if(searchTree.contains(num))
                    {
                        int[] array = searchTree.toArray();
                        index = 0;
                        found = false;
                        while(!found)
                        {
                            if(num == array[index])
                                found = true;
                            else
                                index++;
                        }
                        if(index != 0)
                            System.out.println(array[index-1]);
                        else
                            System.out.println("That was the first one!");
                    }
                    else
                        System.out.println(num + " does not exist! Please try again!");
                    break;
            case "S": num = keyboard.nextInt();
                   if(searchTree.contains(num))
                    {
                        int[] array = searchTree.toArray();
                        index = 0;
                        found = false;
                        while(!found)
                        {
                            if(num == array[index])
                                found = true;
                            else
                                index++;
                        }
                        if(index != array.length-1)
                            System.out.println(array[index+1]);
                        else
                            System.out.println("That was the last one!");
                    }
                    else
                        System.out.println(num + " does not exist! Please try again!");
                    break;
            case "E": System.out.println("Was a tricky one! Thanks for playing ;P");
                    break;
            case "H": System.out.println("I  Insert a value\n" +
                                         "D  Delete a value\n" +
                                         "P  Find predecessor\n" +
                                         "S  Find successor\n" +
                                         "E  Exit the program\n" +
                                         "H  Display this message");
                    break;

            default: System.out.println("Invalid command. Type H for help.");
                    break;
            }
        }
        keyboard.close();
    }
}

1 个答案:

答案 0 :(得分:0)

如果您添加两行代码以打印出employee返回的数组,然后再进入searchTree.toArray()循环,该循环将检查数组以查找由while指定的值或P命令,您将看到问题的原因。数组未正确填写。期望的值可能不会出现在数组中,这意味着S永远不会变为True,并且found循环将继续递增while直到其超过数组的大小并触发您看到的异常。

由于该数组应该由index填充,因此这表明该函数未正确执行其工作。行为异常的原因是它对自身的内部递归调用不会为调用者修改inorderTraverse()变量的值。 count是一个简单的count变量,因此递归调用中的int语句不会影响调用函数中count++的值。

您最好的选择是更改count以使其返回下一个应填写的数组元素的索引,或者将inorderTraverse()更改为包含{{1}的Object }成员,其值在递归调用的函数中递增后将对调用方可见。

由于这是一项作业,因此我不会显示该程序的正确版本。更改很小,因此鉴于您到目前为止所做的一切,我希望您在使其生效方面不会遇到很多麻烦。

顺便说一句,您的程序缺少countintprintIn()的实现。它们并不难编写,但是对于任何可能有兴趣帮助您解决问题的人来说,这都是一个额外的障碍。这可能至少是没有其他人提供答案的原因的至少一部分。您使人们越容易重现问题,获得答案的可能性就越大。