改写二分搜索算法及对于问题的理解

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循环体内,每次将查找的范围缩小一半,循环、判断、减半,直到最后找到记录或者找不到记录时返回。该算法简洁明了,以后会多学习和练习类似的算法。

猜你喜欢

转载自www.cnblogs.com/CYUCHUN/p/9820011.html