先認識順序查找:查找效率低。
使用哨兵的,可以減少邊界結束條件的判斷。
二分查找有靜態的查找和動態的查找。二分查找效率log(N),但是必須時存儲在線性的結構數組中,適合於靜態查找;當用二叉判定樹的時候,方便數據的插入和刪除。
在二分查找中,我們是取mid等於left和right的中間值,即用等分的方法進行查找。
那為什么一定要等分吶?能不能進行“黃金分割”?也就是mid=left+0.618(right-left),當然mid要取整數。如果這樣查找,時間復雜性是多少?也許你還可以編程做個試驗,比較一下二分法和“黃金分割”法的執行效率。
測試:
/*! * \file 二分查找和黃金查找.cpp * * \author ranjiewen * \date 三月 2017 * * */ #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAXLength 10000000 struct Node { int Element[MAXLength]; int Length; }; typedef struct Node *List; clock_t start1, stop1, start2, stop2; double duration; int BinarySearch(List Tbl, int K); int GoldenSearch(List Tbl, int K); int main() { int i, j, result; List Tbl = (List)malloc(sizeof(struct Node)); Tbl->Length = MAXLength - 1; for (i = 0; i < MAXLength; i++){ Tbl->Element[i] = i; } start1 = clock(); for (j = 1; j <= MAXLength - 1; j++){ result = BinarySearch(Tbl, j); } stop1 = clock(); duration = ((double)(stop1 - start1)) / CLK_TCK / (MAXLength - 1); printf("Duration of BinarySearch is %6.2es.\n", duration); start2 = clock(); for (j = 1; j <= MAXLength - 1; j++){ result = GoldenSearch(Tbl, j); } stop2 = clock(); duration = ((double)(stop2 - start2)) / CLK_TCK / (MAXLength - 1); printf("Duration of GoldenSearch is %6.2es.\n", duration); return 0; } int GoldenSearch(List Tbl, int K){ int left, right, mid, NoFound = -1; left = 1; right = Tbl->Length; while (left <= right){ mid = left + 0.618*(right - left); if (K<Tbl->Element[mid]) right = mid - 1; else if (K>Tbl->Element[mid]) left = mid + 1; else return mid; } return NoFound; } int BinarySearch(List Tbl, int K){ int left, right, mid, NoFound = -1; left = 1; right = Tbl->Length; while (left <= right){ mid = (left + right) / 2; if (K<Tbl->Element[mid]) right = mid - 1; else if (K>Tbl->Element[mid]) left = mid + 1; else return mid; } return NoFound; }
結果:二分查找的時間要快些。
其中 編程之美之二分查找總結 里面介紹了很多二分查找的坑。二分查找法的實現和應用匯總 之前參考別人的。