二分查詢其實並不簡單
這個演算法有很多版本
而且變化也比較多 稍一不留神就容易寫錯
這裡總結一下
一般二分查詢
binary_serach
int f(int
array, int key,int len)
else
//cout}
return -1;
}
注意判斷條件必須要這麼寫
因為比如奇數個元素(1,3,5)找5的時候
如果不這麼寫mid = 中間元素後
l變成 mid+1 還沒判斷就已經跳出迴圈了 這個時候如果返回mid的話就會出錯
如果是下面這種lower_bound即使是寫了l
int f(int
array, int key,int len)
else
//cout}
return l;
}
upper_bound 實現
int f(int
array, int key,int len)
else
//cout}
return left;
}
那麼不論是upper還是lower為什麼返回值都是left呢
由於程式是停在right = left-1的情況下
那麼如果是向左逼近 最終導致彈出迴圈的操作一定是
right = mid-1;
因為一定是當前情況滿足條件 繼續逼近 然而left = mid
此時right = left -1 跳出迴圈
我們返回left
如果是向右逼近
最終導致彈出迴圈的操作一定是
left = mid+1;
因為一定是一直向右逼近 執行完這句話有 left = right+1
而right指向key的最後乙個 所以upper_bound應是left
這裡我們就可以推出來
那麼如果我們要查詢的是指定元素的最後乙個
程式只需要改一句話就可以了
int f(int
array, int key,int len)
else
//cout}
return right;
}
就是返回right
二分查詢的訣竅是 不論是要找哪個元素 我們分析一下就能寫出來
一種是找lowerbound 那麼就是找對應元素的下界
也就是當我們找到乙個mid元素》=x的時候 我們要繼續向左逼近 那麼就讓right = mid-1
當找upperbound的時候 也就是要向右逼近 當我們找到乙個mid元素<=x的時候 我們就向右逼近
left = mid+1
查詢第乙個等於或者小於x的某個元素
如果不存在x 就返回第乙個小於x的元素位置
int f(int arr,int x,int
len)
else
}return r;
}
也就是lower_bound中right最終停下的位置 ( lower_bound向左乙個位置)
查詢第乙個等於或者大於key的元素(lower_bound找到返回第乙個 找不到返回大於key的第乙個。)
int f(int arr,int x,int
len)
return l;
}
查詢最後乙個小於key的元素(分析可知其實就是lower_bound的前乙個位置)
int f(int arr,int x,int
len)
return r;
}
查詢第乙個大於k的元素(也就是upper-bound)
int f(int arr,int x,int
len)
return l;
}
大多數情況下的二分查詢都在這裡了
遇到題目的時候還是要仔細分析
用的是哪一種
基本上都是上下界查詢的變形
lowerbound查不到返回第乙個比他大的位置
若沒有比他大的返回最後乙個元素的後乙個元素的位置
即永遠返回插入該元素的適當位置
upperbound查詢查到大於等於某元素的最後乙個位置
即返回要插入元素的適當位置
二分查詢總結
今天上csdn,發現一篇關於二分查詢演算法的文章被置頂,回帖也相當熱烈。我覺得演算法總重要的還是要了解思想,至於程式設計技巧則是其次。二分查詢在計算中演算法中的重要性不言而喻,許多變形的演算法都是基於此演變的,比如二分查詢樹等。所以此演算法程式我也打算總結一下。當然經典的演算法討論莫過於jon be...
二分查詢總結
我們假設乙個最簡單的環境,對於數x,按要求詢問它在乙個陣列a 假設從小到大 裡的位置,陣列個數為n。1.查詢最後乙個小於x的數的位置 常見的一種要求。返回小於x的其中的最右邊乙個數的下標。int half int x return r 2.查詢最後乙個小於或等於x的數的位置 返回小於或等於x的其中的...
二分查詢總結
二分查詢也稱折半查詢 bi nary sear ch binary search binar ysea rch 它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。第一次寫部落格,之所以選這個演算法是因為第一次面試問了這個題,自己學習的時候也沒認真...