在二分搜索应用于未排序的数组时加入部分检测程序—编程珠玑第五章习题5

来源:互联网 发布:jquery confirm.js 编辑:程序博客网 时间:2024/06/06 19:26
在二分搜索应用于未排序的数组时加入部分检测程序—编程珠玑第五章习题5

       大家都知道二分搜索算法应该用在已经排序好的数组中,但是有时候会犯一些错误,一个常见的错误就是把二分搜索应用于未排序的数组,而在每次搜索前检测整个数组是否有序需要进行n-1次额外的比较。
       1.测试,断言优化问题
         可以加入:
                         for(i=0;i<=n-1;i++)
                               assert(a[i]<a[i+1]);
        2.在程序中进行检测
         
[html] view plaincopy
  1. int bs(int *a, int b, int e, int v)    
  2. {    
  3.     int *begin = a + b, *end = a + e, *mid;    
  4.     if (!a || b >= e) return -1;    
  5.     while (begin < end)    
  6.     {    
  7.         mid = begin + ((end - begin) >> 1);    
  8.         assert(*begin <= *mid && *mid <= *end);    
  9.         if (*mid > v) end = mid;    
  10.         else if (*mid < vbegin = mid + 1;    
  11.         else return mid - a;    
  12.     }    
  13.     return -1;    
  14. }    

    上面的那种方法在程序中加入了一些检测条件,但是这个方法需要多次使用才能检测出来,也就是可能在查找某两个数的时候不会报错,但是在查找别的几个数的时候就会报错了。还需要改进。
  1. int bs(int *a, int b, int e, int v)  
  2. {  
  3.     int *begin = a + b, *end = a + e, *mid, i = b;  
  4.     static int *record = 0;  
  5.     if (!a || b >= e) return -1;  
  6.     if (!record || record != a)  
  7.     {  
  8.         while (i < e && a[i] < a[i+1]) ++i;  
  9.         assert(i == e);  
  10.     }  
  11.   
  12.     while (begin < end)  
  13.     {  
  14.         mid = begin + ((end - begin) >> 1);  
  15.         assert(*begin <= *mid && *mid <= *end);  
  16.         if (*mid > v) end = mid;  
  17.         else if (*mid < v) begin = mid + 1;  
  18.         else return mid - a;  
  19.     }  
  20.     return -1;  
  21. }  
    上面程序加上一个static变量来记录这个数组是否经过检测,来决定以后的检测还需要进行。
原创粉丝点击