1. 程式人生 > >資料結構與演算法之美專欄學習筆記-二分查詢(下)

資料結構與演算法之美專欄學習筆記-二分查詢(下)

四種常見的二分查詢變形問題

查詢第一個值等於給定值的元素

//查詢第一個等於給定值的元素
public static int BSearch2(int[] a, int n, int value){
    //定義陣列頭尾索引
    int low = 0, high = n - 1;
    //迴圈到頭索引大於等於尾索引
    while (low <= high){
        //位運算頭尾索引之和除以二得到mid索引,同時避免溢位
        int mid = low + ((high - low) >> 1);
        //根據大小折半比較範圍
        if
(a[mid] > value) high = mid - 1; else if (a[mid] < value) low = mid + 1; //如果和value相等 else{ //如果mid索引是0,或者mid其前一位不等於value //就說明mid處的資料是第一個和value相等的 if (mid == 0 || a[mid - 1] != value) return mid; //否則就以mid前一位為尾索引進行查詢
else high = mid - 1; } } return -1; }

 

查詢最後一個值等於給定值的元素

//查詢最後一個等於給定值的元素
public static int BSearch3(int[] a, int n, int value){
    //定義陣列頭尾索引
    int low = 0, high = n - 1;
    //迴圈到頭索引大於等於尾索引
    while (low <= high){
        //位運算頭尾索引之和除以二得到mid索引,同時避免溢位
        int
mid = low + ((high - low) >> 1); //根據大小折半比較範圍 if (a[mid] > value) high = mid - 1; else if (a[mid] < value) low = mid + 1; //如果和value相等 else{ //如果mid索引是n-1,或者mid其後一位不等於value //就說明mid處的資料是最後一個和value相等的 if (mid == n-1 || a[mid + 1] != value) return mid; //否則就以mid後一位為頭索引進行查詢 else low = mid + 1; } } return -1; }

 

查詢第一個大於等於給定值的元素

//查詢第一個大於等於給定值的元素
public static int BSearch4(int[] a, int n, int value){
    //定義陣列頭尾索引
    int low = 0, high = n - 1;
    //迴圈到頭索引大於等於尾索引
    while (low <= high){
        //位運算頭尾索引之和除以二得到mid索引,同時避免溢位
        int mid = low + ((high - low) >> 1);
        //根據大小折半比較範圍
        //若大於value
        if (a[mid] > value){
            //mid為0或者
            if (mid == 0 || a[mid - 1] < value) return mid;
            else high = mid - 1;
        }
        else low = mid + 1;
    }
    return -1;
}

 

查詢最後一個小於等於給定值的元素

//查詢第一個大於等於給定值的元素
public static int BSearch5(int[] a, int n, int value){
    //定義陣列頭尾索引
    int low = 0, high = n - 1;
    //迴圈到頭索引大於等於尾索引
    while (low <= high){
        //位運算頭尾索引之和除以二得到mid索引,同時避免溢位
        int mid = low + ((high - low) >> 1);
        //根據大小折半比較範圍
        //若大於value
        if (a[mid] < value){
            //mid為0或者
            if (mid == n-1 || a[mid + 1] > value) return mid;
            else low = mid + 1;
        }
        else high = mid - 1;
    }
    return -1;
}

 

適用性分析

凡是能用二分查詢解決的,絕大部分我們更傾向於用散列表或者二叉查詢樹,

即便二分查詢在記憶體上更節省,但是畢竟記憶體如此緊缺的情況並不多。

求“值等於給定值”的二分查詢確實不怎麼用到,二分查詢更適合用在”近似“查詢問題上。比如上面講幾種變體。

 

思考

 

如果有一個有序迴圈陣列,比如4,5,6,1,2,3。針對這種情況,如何實現一個求“值等於給定值”的二分查詢演算法?