![](/img/trans.png)
[英]Why doesn't the binary search method work if the array is sorted in descending order?
[英]Use a Binary Search on an int array sorted in descending order
import java.util.*;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import org.apache.commons.lang3.ArrayUtils;
@SuppressWarnings("unused")
public class Tester {
public static void main(String args[]){
int i[] = {-7, 15, 21, 22, 43, 49, 51, 67, 81, 84, 89, 95, 97};
ArrayUtils.reverse(i);
System.out.println(binarySearch(i, 22));
System.out.println(binarySearch(i, 89));
System.out.println(binarySearch(i, -100));
System.out.println(binarySearch(i, 72));
System.out.println(binarySearch(i, 102));
}
private static int binarySearch(int a[], int srchVal){
int lb = 0;
int ub = a.length - 1;
while(lb <= ub){
int mid = (lb + ub)/2;
if(a[mid] == srchVal){
return mid;
}
else if(srchVal > a[mid]){
lb = mid + 1;
}
else{
ub = mid - 1;
}
}
return -1;
}
}
對於類中的賦值,我需要修改BinarySearch方法,以便它可以與反向數組一起正常工作。 但我無法弄清楚我應該如何修改它。
如果數組按降序排序,則如果反轉搜索算法執行的所有值比較的意義,二進制搜索仍然可以工作。
等於大小寫的情況仍然沒有問題,但你可以將else if
的比較反轉為<
。 else
不需要修改,因為else if
change意味着else
塊現在將代表>
條件。
二進制搜索假設數據是有序的 。 如果是這種情況,則不知道所選索引( mid
)的值是否小於該值,該值必須在0..mid-1
范圍內,反之亦然。
如果數組反向排序,則可以知道如果值較小,則必須在第二部分中搜索。 您必須修改的唯一內容是else if
的條件, else if
:
else if(srchVal < a[mid]){ //change < to >
lb = mid + 1;
}
也就是說,一個更好的方法使該方法更通用,因此可以使比較器更通用:
private static<T> int binarySearch(T[] a, Comparator<T> c, T srchVal){
int lb = 0;
int ub = a.length - 1;
while(lb <= ub){
int mid = (lb + ub)/2;
int ci = c.compare(a[mid],srchVal);
if(ci == 0){
return mid;
}
else if(ci < 0){
lb = mid + 1;
}
else{
ub = mid - 1;
}
}
return -1;
}
如果你提供反向數組,你只需要提供一個Comparator<T>
,它返回-val
其中val
是原始數組的比較器。
有一個hack:1)反向整個數組,現在它正在增加順序數組。 2)應用二進制搜索,然后找到合適的索引。 3)n-index將是你的答案。
二進制搜索適用於有序集。 您的代碼假定訂單是遞增的,但它是反向的。 因此,您需要反轉條件:
while(lb > ub){
更籠統地說,你可能對方向不了解:
private static int binarySearch(int a[], int srchVal, boolean isAscending){
int lb = 0;
int ub = a.length - 1;
while((lb <= ub) == isAscending){
int mid = (lb + ub)/2;
if(a[mid] == srchVal){
return mid;
}
else if(srchVal > a[mid]){
lb = mid + 1;
}
else{
ub = mid - 1;
}
}
return -1;
}
並默認使用升序:
private static int binarySearch(int a[], int srchVal){
return binarySearch(a, srchVal, true);
}
但在你的情況下下降
public static void main(String args[]){
int i[] = {-7, 15, 21, 22, 43, 49, 51, 67, 81, 84, 89, 95, 97};
ArrayUtils.reverse(i);
System.out.println(binarySearch(i, 22), false);
System.out.println(binarySearch(i, 89), false);
System.out.println(binarySearch(i, -100), false);
System.out.println(binarySearch(i, 72), false);
System.out.println(binarySearch(i, 102), false);
}
只需將srchVal> a [mid]條件更改為srchVal <a [mid]
import java.util.*;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
public class HelloWorld{
private static int binarySearch(int a[], int srchVal){
int lb = 0;
int ub = a.length - 1;
while(lb <= ub){
int mid = (lb + ub)/2;
if(a[mid] == srchVal){
return mid;
}
else if(srchVal < a[mid]){
lb = mid + 1;
}
else{
ub = mid - 1;
}
}
return -1;
}
public static void main(String []args){
int i[] = {97,95,89,84,81,67,51,49,43,22,21,15,-7};
System.out.println(binarySearch(i, 22));
System.out.println(binarySearch(i, 89));
System.out.println(binarySearch(i, -100));
System.out.println(binarySearch(i, 72));
System.out.println(binarySearch(i, 102));
}
}
如果要在按降序排序的數組中運行二進制搜索,則可以在二進制搜索中傳遞反向比較器。 例:
Integer [] arr = new Integer[]{5,6,2,9,7};
Arrays.sort(arr, Collections.reverseOrder()); //sorting the array in descending order
Arrays.binarySearch(arr, 2, Comparator.reverseOrder()) // Searches of for 2 in the array.
上面的函數將返回4,這是反向排序數組中的2的索引。 如果元素不存在於數組中,它也可以正常工作。 例如,如果搜索值3,它將返回-5。 (-insertion指數-1)檢查此了解詳情。
謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.