c/c++ 實戰之二分查詢
阿新 • • 發佈:2019-01-08
二分查詢的必要條件
陣列或者集合有序,或者存在一種關係 –> 滿足條件與不滿足條件的資料能夠按照某種標準分成兩部分。最簡單的就是基本資料型別的陣列了。
比如說:我們聲明瞭一個數組 ,如下:
int array [] = {0,1,2,3,4,5,6,7,8,9,10};
假設我們要查詢這個陣列中是否存在一個值9,如果是採用for迴圈遍歷的話,那麼我們需要遍歷10次這個陣列,顯然當資料較多且我們要查詢的值有可能在陣列的尾端時,那麼這種查詢方法的效率並不高。所以機智的人類想到了這種二分查詢法,其原理也相當的簡單。
比如上面這個例子,我們在查詢陣列中是否含有9這個值時,先取陣列的中間位置,也就是index == 5的值進行判斷,如果 9 == array[5] 那麼恭喜!我們剛好查到我們想要的結果,如果9 > array[5]則說明在有序陣列中,我們要查詢的值應該位於array[5] 的右側,否則位於array[5]的左側,很明顯 9 > 5 所以,我們要查詢的值在5的右側,然後我們再取array[6] ~ array[10]的中間值查詢,即array[8],我們發現
9 > 8,那麼值還在array[8]的右側。依此類推,我們只需再查一次便可獲取到結果。對比原始的for迴圈,我們只花了3次便獲取到了結果。其效率非常之高。
下面上c++程式碼:
C++ 二分查詢實現
// CppArray.cpp : 定義控制檯應用程式的入口點。 #include "stdafx.h" #define GET_ARRAY_LEN(array,len) {len=sizeof(array)/sizeof(array[0]);} //統計查詢次數 int count = 0; //折半查詢 int binarySearch(int* array, int start, int end, int search) { int median = (start + end) / 2; if (search < *(array + median)) { //因為search小於陣列中間位置的值,說明在有序陣列中要查詢的結果應該位於中間位置的值的左側 if (median - 1 < 0) { return -1; } return binarySearch(array, start, median, search); } else if (search > *(array + median)) { //因為search大於陣列中間位置的值,說明在有序陣列中要查詢的結果應該位於中間位置的值的右側 if (median + 1 >= end) { return -1; } return binarySearch(array, median, end, search); } else { return search; } } int main() { int num[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12 }; int len; GET_ARRAY_LEN(num, len); for (int i = 13; i >-3; i--) { count = 0; int result = binarySearch(num, 0, len, i); printf("查詢結果 = %d,共花了%d次\n",result, count); } return 0; }
正如程式碼中所示,我們從13開始一直查詢到-2,結果如圖所示:
我們要查詢的值最多的也才花費4次。當然對於資料不大的話使用這種查詢可能沒什麼必要,但是當資料量大的時候,比如查詢一個長度為250的陣列,那效率就不一般了,在Android中用過SparseArray或者有去了解過SparseArray具體實現的各位大佬們一定深有體會!