算法第二章上机实践报告
1.实践题目
改写二分搜索算法
2.问题描述
设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
输入格式:
输入有两行:
第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。
输出格式:
输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。当搜索元素在数组中时,i和j相同。 提示:若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值
3.算法描述
用二分法对待排序列进行搜索,如果存在的话就返回i=j=mid,mid是x在给定序列的数组下标;如果不存在的话,返回i=right&&j=left,至于为什么不返回i=left&&j=right,是因为在算法设计的时候,发现当找不到时,总会出现left==right的情况,此时它们都指向小于x的最大数,所以在循环中令left再加多一次,因为序列有序,此时left指向的必定是大于x的最小数。
具体代码如下:
#include<iostream>
using namespace std;
int Binary(int a[], int k, int n) {
int left = 0;
int right = n - 1;
int i = 0,j=0;
while (left <= right) {
int mid = (left + right) / 2;
if (k == a[mid])
{
i = j = mid;
cout << i <<" "<<j<<endl;
return mid;
}
if (k > a[mid])left = mid + 1;
else { right = mid - 1; }
}
i = right;
j = left;
cout << i<<" "<< j<<endl;
return -1;
}
int main() {
int n;
int x;
cin >> n>> x;
int *a = new int [n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
Binary(a, x, n);
}
4.时间、空间复杂度
时间复杂度:由主定理得:T(n)=2T(n/2)+O(1)=O(logn)
空间复杂度:各个变量的空间复杂度都是O(1),所以算法空间复杂度为O(1)
5.心得体会
1.解决问题要学会放弃,一条路不行就马上找另一条,不要钻牛角尖,一开始总是想着找i\j\mid的关系,纠结了好久还是没有想出来。
2.要学会利用一个具体事例来确定问题的规律,别傻乎乎的瞎想。
3,跟队友讲思路会有助于将思路理清,毕竟跟别人讲得含糊他肯定也听得出来,肯定会提出各种duang、duang、duang的问题,回答完这些问题后,题目估计就AC了