1. 程式人生 > >改寫二分搜尋演算法及對於問題的理解

改寫二分搜尋演算法及對於問題的理解

1、實踐題目:

 改寫二分搜尋演算法

 2、問題描述:

 設陣列a[0:n-1]已排好序,輸入一個整數x

 ①當x不在陣列中時,返回小於x的最大元素位置i和大於x的最小元素位置j

 ②當x在陣列中時,ij相同,均是x在陣列中的位置。

 輸入:第一行是n值和x值,第二行是n個不相同的整陣列成的非降序序列,每個整數之間以空格分隔。

 輸出:小於x的最大元素的最大下標i和大於x的最小元素的最小下標j。當搜尋元素在陣列中時,ij相同。

 提示:x小於全部數值,則輸出:-1 , x大於全部數值,則輸出:n-1的值,n的值

3、演算法描述:

 1)定義兩個函式,主函式

main()和二分搜尋演算法函式BinarySearch()。在函式BinarySearch()中,定義關鍵字key表示要查詢的值x,定義一個長度為n的陣列a[n]

 2)利用二分搜尋的思想,在陣列中查詢關鍵字key。當left<=right,如果key==a[mid],則表示x在陣列中,返回下標ij,如果key>a[mid],則left=mid+1,如果key<a[mid],則 right=mid-1,不斷減半、迴圈,縮小範圍查詢,直到left>right,如果還是沒有找到x,則把right賦值給ileft賦值給就j,然後返回下標ij

 3)返回小於x的最大元素位置

i和大於x的最小元素位置j

4、演算法部分程式碼:

 1 int BinarySearch(int a[], int key, int n) {
 2     int left = 0, right = n - 1;
 3     int i = 0, j = 0;
 4     while (left <= right) {
 5         int mid = (left + right) / 2;
 6         if (key == a[mid])
 7         {
 8             i = j = mid;
 9             cout << i <<"
"<<j<<endl; 10 return mid; 11 } 12 if (key > a[mid]) left = mid + 1; 13 else { right = mid - 1; } 14 } 15 i = right; 16 j = left; 17 cout << i<<" "<< j<<endl; 18 return -1; 19 }

5、演算法時間複雜度和空間複雜度:

 ①時間複雜度:迴圈體每迴圈一次時間複雜度減少一半,而且判斷的時間複雜度為O(1),所以根據公式得演算法時間複雜度為T(n)=1*T(N/2)+O(1)=O(logn)

 ②空間複雜度:各個變數的空間複雜度都是O(1),所以演算法空間複雜度為O(1)

 6、心得體會:

 經過這次小組上機實踐,我對於二分搜尋演算法有了更深刻的瞭解。在一開始,我和隊友直接採用非二分法的方法,導致時間複雜度不符合要求,後來經過老師提醒和隊友間的合作,最終完成了任務。二分搜尋在while迴圈體內,每次將查詢的範圍縮小一半,迴圈、判斷、減半,直到最後找到記錄或者找不到記錄時返回。該演算法簡潔明瞭,以後會多學習和練習類似的演算法。