使用递归方法进行三叉搜索

时间:2014-08-31 15:14:17

标签: java arrays algorithm recursion

我正在编写一种递归方法,它不是执行二进制搜索算法,而是将数组拆分为三个并使用三元搜索算法。我相当肯定我的递归情况是正确的,但我的基本情况似乎有问题。如果数组包含两个或更少的值,那么基本情况应该是非递归检查,如果该值在数组中并返回索引。如果找不到该值,则返回-1。

由于我无法弄清楚的原因,这种方法无论如何都会返回-1。无论数组的大小,还是数组是否包含该值。这是方法。

public static int trinarySearch(int[] array, int x, int low, int high) {

    if (high - low < 3) { //BASE CASE.
        for (int i = low; i < high; i++) {
            if (array[i] == x) {
                return i;
            }
        }
        return -1;
    } else { //RECURSIVE CASE.

        int firstThird = low + (high - low) / 3;
        int secondThird = low + 2 * (high - low) / 3;

        if (x <= array[firstThird]) {
            return trinarySearch(array, x, low, firstThird - 1);
        } else if (x <= array[secondThird]) {
            return trinarySearch(array, x, firstThird + 1, secondThird - 1);
        } else { // must be (x > array[secondThird])
            return trinarySearch(array, x, secondThird + 1, high);
        }
    }
}

在我的测试代码中,我只是将数组设置为int [] array = {1,2,.....}

让我说我搜索int 2,它在数组中。我在测试代码中设置了一个数组,并将该方法称为trinarySearch(array,2,0,array.length-1)。它每次打印-1。该方法有问题,或者我只是设置错误的测试代码?

3 个答案:

答案 0 :(得分:1)

您似乎在混淆lowhigh的逻辑。通常,您可以将检查中的子阵列定义为从low(包括)开始,到high(不包括)结束。

您使用high包含(正如我在您使用array.length-1的示例调用中所理解的那样),但随后循环播放

for (int i = low; i < high; i++) {

不访问array[high]

快速解决方法是将<更改为<=,您的代码运行正常。但是,我建议使用标准定义(高级别),因为它还简化了代码的其他部分:

  • 您不需要任何容易出错的+1-1索引修补程序(不要忘记将<=更改为<你的递归案例)。
  • high-low是受检查的子阵列的大小,因此您可以使用high-low <= 3更清楚地显示您的基本案例处理长度为3的数组。

答案 1 :(得分:0)

我认为你并不了解Heuster的回答。这就是我要做的事情,在我看来Heuster说的是同样的话:

public static int trinarySearch(int[] array, int x, int low, int high) {

        if (high - low < 3) { //BASE CASE.
            for (int i = low; i < high; i++) {
                if (array[i] == x) {
                    return i;
                }
            }
            return -1;
        } else { //RECURSIVE CASE.
            int firstThird = low + (high - low) / 3;
            int secondThird = low + 2 * (high - low) / 3;

            if (x < array[firstThird]) {
                return trinarySearch(array, x, low, firstThird);
            } else if (x < array[secondThird]) {
                return trinarySearch(array, x, firstThird, secondThird);
            } else { // must be (x > array[secondThird])
                return trinarySearch(array, x, secondThird, high);
            }
        }
    }

答案 2 :(得分:0)

您刚刚错过了递归部分中的一个重要条件,即if(x==splitingIndex)

我已经改变了你的代码并且工作了 查看更改

public static int trinarySearch(int[] array, int x, int low, int high) {

    if (high - low < 3) { 
        //BASE CASE.
        for (int i = low; i < high; i++) {
            if (array[i] == x) {
                return i;
            }
        }
        return -1;
    } else { //RECURSIVE CASE.

        int firstThird = low + (high - low) / 3;
        int secondThird = low + 2 * (high - low) / 3;

        if(x == array[firstThird])
        {
            return firstThird;
        }
        else if (x < array[firstThird]) {
            return trinarySearch(array, x, low, firstThird - 1);
        }

        if(x == array[secondThird])
        {
            return secondThird;
        }
        else if (x < array[secondThird]) {
            return trinarySearch(array, x, firstThird + 1, secondThird - 1);
        }



            return trinarySearch(array, x, secondThird + 1, high);
        }
    }