二分查找

**
二分查找算法的前置條件是,一個已經(jīng)排序好的序列(在本篇文章中為了說明問題的方便,假設這個序列是升序排列的),這樣在查找所要查找的元素時,首先與序列中間的元素進行比較,如果大于這個元素,就在當前序列的后半部分繼續(xù)查找,如果小于這個元素,就在當前序列的前半部分繼續(xù)查找,直到找到相同的元素,或者所查找的序列范圍為空為止.

時間復雜度: O(lgN)

int bSearch(int *a,int len,int target)
{
    int low = 0;
    int high = len-1;
    int mid;
//注意此處是low<=high不是low<high
    while(low<=high)
    {
        mid = low+((high-low)>>1);
        if (a[mid] == target)
            return mid;
        else if(a[mid] > target)
            high = mid-1;
        else
            low = mid+1;
    }
    return -1;
}

上面的程序的問題在于:
1.如果序列當中有多個元素相同時,查找的時候不見得每次都會返回第一個元素的位置。
2.每次循環(huán)體當中都有三種情況,兩次比較,有沒有辦法減少比較的數(shù)量,進一步優(yōu)化程序。

《編程珠璣》中給出了解決這個問題的算法,如下:

int bSearch(int *a,int len,int target)
{
    int low = -1;
    int high = len;
    int mid;

    while(low+1 != high)
// 這個循環(huán)維持的條件是 low < high &&a[low]<target<a[high],
//所以最后若可以找到目標,則只剩下兩個數(shù),并滿足a[low]<target<a[high],要查找的數(shù)就是high.
    {
        mid = low+((high-low)>>1);
        if(a[mid] < target)
//必須保證a[low]<target<=a[high],所以low=mid.
//若low = mid+1,則可能出現(xiàn)a[low] <=target
            low = mid;
        else
            high = mid;
    }
    if(high >= len || a[high] != target)
        high = -1;
    return high;

}

上面的算法不好理解,也可以使用下面這種。

int bSearch(int *a,int len,int target)
{
    int low = 0;
    int high = len-1;
    int mid;
    int last =-1;
//定義一個last來記錄查找到的元素最后一次出現(xiàn)的位置。
//賦初始值為-1,當所要查找的元素不存在時,就能直接返回-1.
    while(low<=high)
    {
        mid = low+((high-low)>>1);
        if (a[mid] < target)
            low = mid+1;
        else if(a[mid] > target)
            high = mid-1;
        else
        {
            last =mid;
            high = mid-1;
        }
    }
    return last;
}

另外,若要求的是找到大于某個數(shù)的第一個數(shù),則可以使用如下方法:

int bSearch(int *a,int len,int target)
{
    int low = 0;
    int high = len-1;
    int mid;
    int last = -1;
    while(low<=high)
    {
        mid = ((high-low)>>1)+low;
        if (a[mid] > target)
        {
            last = mid;
            high = mid-1;
        }
        else
            low = mid+1;
    }
    return last;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 介紹 當我們想在一個數(shù)組中查找一個元素的時候,最簡單的方法莫過于順序查找了,不過順序查找有一個致命的缺點,就是它的...
    ghwaphon閱讀 987評論 0 12
  • 1 前言 二分查找本身是個簡單的算法,但是正是因為其簡單,更容易寫錯。甚至于在二分查找算法剛出現(xiàn)的時候,也是存在b...
    __七把刀__閱讀 1,579評論 0 1
  • 二分查找 二分查找算法是一種在有序數(shù)組中查找某一特定元素的搜索算法。搜素過程從數(shù)組的中間元素開始,如果中間元素正好...
    JasonDing閱讀 1,594評論 0 3
  • 二分查找二分查找 又稱折半查找,要求數(shù)組必須是有序的數(shù)列,是一種有序查找算法。二分查找的時間復雜度是O(log n...
    VV木公子閱讀 1,420評論 0 12
  • 國慶后的某天,我又拖著行李箱背著電腦踏上出差的旅途。于是我平生第一次見到了自殺。 當我從車站二樓搭乘電梯下去的時候...
    千分之一閱讀 653評論 3 11

友情鏈接更多精彩內(nèi)容