我正在编写一种递归方法,它不是执行二进制搜索算法,而是将数组拆分为三个并使用三元搜索算法。我相当肯定我的递归情况是正确的,但我的基本情况似乎有问题。如果数组包含两个或更少的值,那么基本情况应该是非递归检查,如果该值在数组中并返回索引。如果找不到该值,则返回-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。该方法有问题,或者我只是设置错误的测试代码?
答案 0 :(得分:1)
您似乎在混淆low
和high
的逻辑。通常,您可以将检查中的子阵列定义为从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);
}
}