問題描述:ios
給定已排好序的n個元素組成的數組,現要利用二分搜索算法判斷特定元素x是否在該有序數組中。算法
細節須知:數組
(1)因爲可能須要對分治策略實現二分搜索的算法效率進行評估,故使用大量的隨機數對算法進行實驗(生成隨機數的方法見前篇隨筆)。dom
(2)因爲二分搜索須要數據爲有序的,故在進行搜索前利用函數庫中sort函數對輸入的數據進行排序。函數
(3)代碼主要用到的是經典的二分查找加上遞歸。spa
(4)其中limit爲所要從隨機數文件中提取的數據的數量,以此爲限來決定算法須要在多少個數據中進行搜索。設計
(5)爲了使代碼更人性化,加入了查找成功與失敗的提醒,主要區別於Search函數中的返回值,若查找成功則返回1(知足1>0,即爲查找成功),其他則返回0,即爲查找失敗。code
(6)經過clock函數對算法運行的時間進行計算以評估算法效率。blog
算法原理:排序
假設搜索範圍爲數組a中的n個元素,要搜索的元素爲x。
將n個元素分紅個數大體相同的兩半,取a[n/2]與x進行比較。若是x=a[n/2],則找到x,算法終止。若是x<a[n/2],則只要在數組a的左半部繼續搜索x。若是x>a[n/2],則只要在數組a的右半部繼續搜索x。以此不斷地將搜索範圍折半,從而實現採用分治策略進行二分搜索。
1 #include <iostream>
2 #include <fstream> 3 #include <cstdlib> 4 #include <ctime> 5 #include <algorithm> 6 using namespace std; 7 #define limit 100000 8 9 int Search(int R[],int low,int high,int k) //low表示當前查找的範圍下界、high表示當前查找範圍的上界,k爲所要查找的內容 10 { 11 int mid; 12 13 if (low<=high){ //查找區間存在一個及以上元素 14 mid=(low+high)/2; //求中間位置 15 if (R[mid]==k) //查找成功返回1 16 return 1; 17 if (R[mid]>k) //在R[low..mid-1]中遞歸查找 18 Search(R,low,mid-1,k); 19 else //在R[mid+1..high]中遞歸查找 20 Search(R,mid+1,high,k); 21 } 22 else 23 return 0; 24 } 25 26 int main(void) 27 { 28 ifstream fin; 29 int x; 30 int i; 31 int a[limit]; 32 int result; 33 34 fin.open("random_number.txt"); 35 if(!fin){ 36 cerr<<"Can not open file 'random_number.txt' "<<endl; 37 return -1; 38 } 39 40 time_t first, last; 41 42 for(i=0; i<limit; i++){ 43 fin>>a[i]; 44 } 45 fin.close(); 46 47 sort(a,a+limit); 48 49 cout<<"Please enter the number you want to find:"; 50 cin>>x; 51 52 first = clock(); 53 54 result = Search(a,0,limit-1,x); 55 56 if(result>0) 57 cout<<"Search success!"<<endl; 58 else 59 cout<<"Can not find it!"<<endl; 60 61 last = clock(); 62 63 cout<<"Time cost: "<<last-first<<endl; 64 65 return 0; 66 }
程序設計思路:
若x等於中間項,則退出。不然,
(1)將數組劃分爲兩個子數組,其大小大約爲原數組的一半。若是x小於中間項,則選擇左子數組;若是x大於中間項,則選擇右子數組。
(2)肯定x是否在該子數組中,以解決該子數組。若是該子數組不夠小,則進行遞歸處理。
(3)由子數組的答案得到原數組的答案。
結果數據格式爲time_t格式相減獲得的長整型。
時間複雜性分析:
假設搜索範圍爲數組a中的n個元素,要搜索的元素爲x。
將n個元素分紅個數大體相同的兩半,取a[n/2]與x進行比較。若是x=a[n/2],則找到x,算法終止。若是x<a[n/2],則只要在數組a的左半部繼續搜索x。若是x>a[n/2],則只要在數組a的右半部繼續搜索x。以此不斷地將搜索範圍折半,從而實現採用分治策略進行二分搜索。
其中,每執行一次算法的循環,待搜索數組的大小減小一半。在最壞狀況下(即x大於全部數組項),若是n是2的冪,並且x大於全部數組項目,那每次調用生成的實例剛好爲原實例的一半;若n=1,且x大於這個惟一數組項目,會將x與此項目進行比較,後面是在low>high條件下的一次遞歸調用。於是,肯定遞推關係:
W(n)=W(n/2)+1 (n>1,n爲2的冪)
W(1)=1
由Master方法能夠獲得
W(n)=lgn+1
若是n不只侷限於2的冪,則
W(n)=⌊lgn⌋+1∈O(lgn)
其中⌊y⌋表示小於或等於y的最大整數。