簡體   English   中英

在int數組上使用二進制搜索按降序排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM