算法第二章上机实践报告

 实践题目:

二分查找

输入n值(1<=n<=1000)、n个非降序排列的整数以及要查找的数x,使用二分查找算法查找x,输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。

输入格式:

输入共三行: 第一行是n值; 第二行是n个整数; 第三行是x值。

输出格式:

输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。

输入样例:

4
1 2 3 4
1

输出样例:

0
2
  • 问题描述:此题相比二分查找多了一个查找不到时要求输出-1,以及总的比较次数

 

  • 算法描述:用变量count来存放比较次数并将其自加语句放置在循环体头,就不用每次都在if语句后面写了
int count = 0;
        while(l <= r){
            count ++;
                    ....
                }

   比较要查找的数x时,二分查找

int m =(l + r) / 2;
if(x == a[m]) {
    cout << m <<endl << count;
    return m;
}
if(x > a[m]){
    l = m+1;
}    
else {
    r = m-1;
}

  当要查找的数不存在时,即不符合循环体,跳出循环体,输出-1,同时输出比较次数

cout << "-1" <<endl << count;
return -1;

  具体算法如下,以下给出的是递归的算法,与以上如出一辙,只不过递归算法中,把是否找到放在了循环体外,用来直接为输出服务,不干扰递归调用

int BS(int a[],int x, int l, int r, int &count){

        count ++;
        if( l == r){
            if(x == a[l])
                return l;
    
            else return -1;
        }
        while (l < r){
            int m = (l + r) / 2;
            if(x == a[m]) {
                 return m;
            }
            if(x < a[m]){
                return BS(a, x, l, m-1, count);
            }
            if(x > a[m]){
                return BS(a, x, m+1
  • 算法时间及空间复杂度分析:查找x是否在非降序序列中,在此用的是二分搜索方法。每次都将x与序列中间的值进行比较,相等表示找到;不等继续在其左边/右边查找,如此折半直到找不到为止,每次都是一半一半,故最后时间复杂度为O(logN);而由于在查找过程中没有使用其他辅助空间,为原地操作,故空间复杂度为O(1)。

 

  • 心得体会:在递归算法实现主函数时,出现了一点小插曲,如下:
int main(){
    int a[1005];
    int n, x, count = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
    cin >> x;
    cout << BS(a, x, 0, n-1, count) << count << endl ;
    return 0;
}

 

  这样的结果是每次输出的结果都是count的初始化值,而解决办法如下:

cout << BS(a, x, 0, n-1, count) << endl ;
cout<< count;

  分开写输出语句,因为在调用BS算法时,直接连续输出两个结果,会导致BS算法中后续的结果在位置上失守,使得count值传递不到位......

 


上一篇:linux中dd命令详解


下一篇:AES上传文件加密下载文件解密(完整,附助手实体类)