二分搜尋
折半搜尋,也稱二分查詢演算法、二分搜尋,是一種在有序陣列中查詢某一特定元素的搜尋演算法。搜素過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜素過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。
時間複雜度:二分搜尋每次把搜尋區域減少一半,很明顯時間複雜度為o(logn)。
空間複雜度:o(1),雖以遞迴形式定義,但是尾遞迴,可改寫為迴圈。
二分搜尋的基本實現
二分查詢法在演算法家族大類中屬於「分治法」,分治法基本都可以用遞迴來實現的,二分查詢法的遞迴實現如下:
int binary_search(int array, int low, int high, int非遞迴實現:target)
int binary_search(int arr,int n ,int關於二分搜尋,想起之前看過的一道題目:乙個陣列是由乙個遞減數列經過若干次左移形成的,例如是由陣列 經過兩次左移形成的,在這種陣列中查詢某乙個數。函式原型是 int search(int a,int low,int high,int k);key)else
} return -1;//
沒有找到元素,返回-1
}
陣列的形態如圖所示:
仔細想想,如果取中間元素對陣列進行劃分的話,那麼陣列可以分為兩個部分,陣列的兩個部分不外乎三種情況:
有序 mid 有序
部分有序 mid 有序
有序 mid 部分有序
這樣遞迴下去,用二分查詢的一種變形,一樣可以查詢出。**如下:
int bsearch(int a, int n, int搜狗還有一道面試題目:key)
else
} else
else
} }
return -1
; }
有乙個陣列,該陣列的特點是:前一部分遞增有序,後一部分遞減有序,求陣列的峰值位置。
我們發現,給出的陣列可能有如下三種形態:
其中後兩種情況是屬於特殊的,是有序陣列,峰值的位置就是陣列的開始或結束索引。我們單單考慮第一種情況。
思考1:線性掃瞄,思路最簡單,也最容易實現,只需掃瞄 一遍陣列,比較當前元素與前乙個元素的大小關係,一旦碰到當前元素比前一元素小,前一元素就是峰值。或者比較當前元素與後一元素,一旦後一元素比當前元素小,當前元素就是峰值。此方法的缺點是需要線性時間o(n)
思考2:考慮二分搜尋,如果不考慮情況2和情況3.對於情況一而言,mid中間元素的位置不外乎三個情況:
是不是跟二分搜尋很類似?
我們可以根據中間元素與兩邊元素的大小關係,判斷搜尋左邊還是右邊。據此,不難寫出如下**(未經嚴格測試):
#include //陣列是先增後減陣列。
int findmax(int *a ,int
n)else
if(a[mid] >= a[mid-1] && a[mid] <=a[mid + 1
])else
}else
if((mid+1) <=high)
else
}else
else
} }
}
intmain();
printf(
"%d \n
",findmax(a,8
));
}
二分搜尋及其擴充套件
二分搜尋需要注意開閉區間的問題,限制條件和邊界要保持配對 low high low mid 1 high mid 1。二分搜尋的模板如下 cpp view plain copy 二分搜尋 intbinarysearch int num,intkey,intlow,inthigh return low...
二分搜尋以及其擴充套件形式
歡迎 如有錯誤敬請指正 二分搜尋使用的前提是陣列必須有序,在本文中,我們用lo low 表示查詢範圍的起始下標,hi hight 表示查詢範圍的結束下標,mid表示lo和hi的中間位置。1.一般情況二分搜尋 普通二分搜尋,如果找到key,返回任意乙個和key相等的元素下標,否則返回 1 public...
二分搜尋及其擴充套件(迴圈遞增陣列的搜尋)
二分搜尋需要注意開閉區間的問題,限制條件和邊界要保持配對 low high low mid 1 high mid 1。二分搜尋的模板如下 cpp view plain copy 二分搜尋 intbinarysearch int num,intkey,intlow,inthigh return low...