改寫二分搜尋演算法及對於問題的理解
1、實踐題目:
改寫二分搜尋演算法
2、問題描述:
設陣列a[0:n-1]已排好序,輸入一個整數x。
①當x不在陣列中時,返回小於x的最大元素位置i和大於x的最小元素位置j。
②當x在陣列中時,i和j相同,均是x在陣列中的位置。
輸入:第一行是n值和x值,第二行是n個不相同的整陣列成的非降序序列,每個整數之間以空格分隔。
輸出:小於x的最大元素的最大下標i和大於x的最小元素的最小下標j。當搜尋元素在陣列中時,i和j相同。
提示:若x小於全部數值,則輸出:-1 , 若x大於全部數值,則輸出:n-1的值,n的值
3、演算法描述:
1)定義兩個函式,主函式
2)利用二分搜尋的思想,在陣列中查詢關鍵字key。當left<=right,如果key==a[mid],則表示x在陣列中,返回下標i,j,如果key>a[mid],則left=mid+1,如果key<a[mid],則 right=mid-1,不斷減半、迴圈,縮小範圍查詢,直到left>right,如果還是沒有找到x,則把right賦值給i,left賦值給就j,然後返回下標i,j。
3)返回小於x的最大元素位置
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迴圈體內,每次將查詢的範圍縮小一半,迴圈、判斷、減半,直到最後找到記錄或者找不到記錄時返回。該演算法簡潔明瞭,以後會多學習和練習類似的演算法。