幾種情況的二分寫法
阿新 • • 發佈:2018-12-31
之前總是對二分的邊界問題把握的不是很好,以致於出現死迴圈等問題。所以用這篇博文進行總結。
首先,本文所用演算法均為左閉右閉的演算法,且陣列是以非遞減順序排列的。
1、查詢是否存在關鍵值,如有相等的,則返回最左邊的那個值的位置。否則,返回-1.
int binary_search_1(int a[], int n, int key) { int m, l = 0, r = n - 1;//閉區間[0, n - 1] while (l < r) { m = l + ((r - l) / 2);//向下取整 if (a[m] < key) l = m + 1; else r = m; } if (a[r] == key) return r; return -1; }
2、查詢是否存在關鍵值,如有相等的,則返回最右邊那個值得位置。否則,返回-1.
int binary_search_2(int a[], int n, int key) { int m, l = 0, r = n - 1;//閉區間[0, n - 1] while (l < r) { m = l + ((r - l + 1) / 2);//向上取整 if (a[m] <= key) l = m; else r = m - 1; } if (a[l] == key) return l; return -1; }
3、查詢最小的比關鍵值大的位置。
int binary_search_3(int a[], int n, int key) { int m, l = 0, r = n - 1;//閉區間[0, n - 1] while (l < r) { m = l + ((r - l) / 2);//向下取整 if (a[m] <= key) l = m + 1; else r = m; } if (a[r] > key) return r; return -1; }
4、查詢最大的比關鍵值小的位置。
int binary_search_4(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//閉區間[0, n - 1]
while (l < r)
{
m = l + ((r - l + 1) / 2);//向上取整
if (a[m] < key)
l = m;
else
r = m - 1;
}
if (a[l] < key) return l;
return -1;
}
5、查詢最小的大於等於關鍵值的位置。
int binary_search_5(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//閉區間[0, n - 1]
while (l < r)
{
m = l + ((r - l) / 2);//向下取整
if (a[m] <= key)
l = m + 1;
else
r = m;
}
if (a[r] >= key) return r;
return -1;
}
6、查詢大的小於等於關鍵值的位置。
int binary_search_6(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//閉區間[0, n - 1]
while (l < r)
{
m = l + ((r - l + 1) / 2);//向上取整
if (a[m] < key)
l = m;
else
r = m - 1;
}
if (a[l] <= key) return l;
return -1;
}
另外:
1、找最小(左)的就向下取整。找最大(右)的就向上取整。
2、如果向下取整了,l+1.如果向上取整了,r-1.
3、對於帶等號的情況來說。尋找最小(左)的就是key <= a[m]。尋找最大(右)的就是key >= a[m].
4、對於不帶等號的兩種情況,把以上括號減掉。
5、最後判斷條件根據情況而定。但是如果是最小(左)的是a[r],最大(右)的是a[l]