需要帮助查看我的二进制搜索程序

时间:2013-05-07 23:14:04

标签: java

我正在尝试用Java实现二进制搜索,但我的代码存在一些问题。如果我要查找的元素存在于数组中,它就可以工作。如果没有,程序不会打印错误消息。我的意思是 -

当我运行我的代码时 - 这是输出 -

Please enter array size
2
Please enter element 0
3
Please enter element 1
4
Sorted array elements[3, 4]


Please enter the element you want to find in the array
3
Match 3 found at index 0

但是,如果我查找数组中不存在的元素,程序不会进入else循环,并打印错误消息 - 而是执行此操作 -

Please enter array size
2
Please enter element 0
3
Please enter element 1
4
Sorted array elements[3, 4]


Please enter the element you want to find in the array
2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at arraysPract.BinarySearch.findElement(BinarySearch.java:82)
    at arraysPract.BinarySearch.main(BinarySearch.java:54)

这是代码 -

package arrays;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class BinarySearch {
    static int[] binaryArr = null;

    public static void main(String[] args) {
        BufferedReader br = null;
        String size = "";

        try {
            System.out.println("Please enter array size");
            br = new BufferedReader(new InputStreamReader(System.in));
            size = br.readLine();
            if (size == null) {
                System.out.println("Size can't be null");
                return;
            }
            int ipSize = Integer.parseInt(size);
            binaryArr = new int[ipSize];
            String entry = "";
            for (int i = 0; i < ipSize; i++) {
                System.out.println("Please enter element " + i);
                entry = br.readLine();
                if (entry == null) {
                    System.out.println("Value can't be null");
                    return;
                }
                int arrEntry = Integer.parseInt(entry);
                binaryArr[i] = arrEntry;
            }

            Arrays.sort(binaryArr);
            System.out.println("Sorted array elements"  + Arrays.toString(binaryArr));
            System.out.println("\n");

            System.out.println("Please enter the element you want to find in the array");
            String findArrayElement = br.readLine();
            int find = Integer.parseInt(findArrayElement);      
            boolean elementExists = Arrays.asList(binaryArr).contains(find);            
            if (elementExists==false) {             
                findElement(binaryArr, find);
            }

            else {
                System.out.println("Element does not exist. Please try again");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static int findElement(int[] test, int keyElement) {
        boolean flag = true;
        int i = 0;
        for (i = test.length / 2; i >= 0 && i < test.length;) {
            if (keyElement == test[i]) {
                flag = false;
                break;
            } else if (keyElement > test[i]) {
                i++;
                if (keyElement == test[i]) {
                    flag = false;
                } else {
                    flag = true;
                }
            } else if (keyElement < test[i]) {
                i--;
                if (keyElement == test[i]) {
                    flag = false;
                } else {
                    flag = true;
                }
            }
        }

        if (flag == false) {
            System.out.println("Match " + keyElement + " found at index " + i);
        }
        return i;
    }
}

如果我忽略了一个明显的错误,请求某人指导我吗?

此外,此帖子有几个可能的重复项 - Binary search in javaBinary search in java等。我只需要帮助审核我的代码,而不是实施该程序:)

4 个答案:

答案 0 :(得分:0)

这不是二分搜索,你应该将索引除以2(或者在递归版本中重复出现)。相反,你在数组的两半进行线性搜索,复杂(线性因为索引递增/递减1,每一步都是常量)。

无论如何,你2的问题是它小于数组的最小元素,所以i递减直到它达到0(第一个元素);此时,执行此行:

i--;

然后,调用test[i]进行比较。但i将为-1,超出范围。测试后调用i--,而不是之前。

请丢弃您的代码,仔细阅读this good reference并正确实施二进制搜索:如果您了解二进制搜索的工作原理,代码非常简单。

编辑:看一下here进行线性搜索。

答案 1 :(得分:0)

它不是二进制搜索,因为您只是迭代数组的上半部分或下半部分。这提供了O(n / 2)的性能,或者换句话说O(n)。二进制搜索连续将其搜索的区域减半,这提供了O(log n)。

在这段代码中:

        } else if (keyElement > test[i]) {
            i++;
            if (keyElement == test[i]) {

此块中的第二个if语句不执行任何操作,您知道keyElement> test[i],因此它也不能相等!

答案 2 :(得分:0)

让我尝试清理一下二叉树是什么,希望它能让你的代码更容易编写。

二进制搜索可以被认为是散布在树中的一堆变量。例如,如果树的根或顶部的数字为8,那么落到左侧的所有内容都小于或等于8,并且分支到该节点右侧的所有内容都会更大。

答案 3 :(得分:0)

无论您是否使用正确的算法,您的代码抛出ArrayOutOfBoundsException的原因是在递增或递减的情况下您继续增加或减少i我将该标志设置为false。在进入循环迭代找到匹配的情况下,你就会脱离循环;在另外两种情况下,您递增/递减循环然后再次检查,但如果更改了标志,则不会中断。这将是使用while或do / while循环更好的情况。如果在增加或减少后删除第二次检查,您将达到您的意思。

就算法而言,你没有递增数组索引,你每次通过数组都会将搜索范围缩小一半。

从中获取的有用之处在于异常和堆栈跟踪会告诉您错误(数组索引为-1)及其发生的位置,方法和行(在ArraysPract.BinarySearch.findElement(BinarySearch.java: 82)