二分查找及扩展

面试常让写二分查找或其扩展的程序,以前总觉得很简单,但是真动手写起来,细节很多,容易出错的地方也很多,真是秒杀眼高手低的利器,本节就二分查找以及相关扩展程序都实现一下,同时将可能出错的地方以及需要注意的细节也一并说明,水平有限,欢迎补充。

内容如下:

1)二分查找元素key的下标,如无 return -1

2)二分查找返回key(可能有重复)第一次出现的下标,如无return -1

3)二分查找返回key(可能有重复)最后一次出现的下标,如无return -1

4)二分查找返回刚好小于key的元素下标,如无return -1

5)二分查找返回刚好大于key的元素下标,如无return -1


http://www.ahathinking.com/archives/179.html

看了这个写的后觉得很难理解, 自己写了一个  

1)二分查找元素key的下标,如无 return -1

  1. #include <stdio.h>  
  2. #define ARRAY_LEN(array) sizeof(array)/sizeof(array[0])  
  3.   
  4. int is_sort_asc(int array[], int length)  
  5. {  
  6.     int i = 0;  
  7.     if(length <= 0)  
  8.     {  
  9.         return -1;  
  10.     }  
  11.     for(i = 0; i < length - 1; i++) --------------------------------------->注意条件  
  12.     {  
  13.         if(array[i] > array[i+1])  
  14.         {  
  15.             return -1;  
  16.         }  
  17.     }  
  18.     return 0;  
  19. }  
  20.   
  21.   
  22. int binary_search(int array[], int left, int right, int key)  
  23. {  
  24.     int mid = 0;  
  25.     if(right <= 0)  
  26.     {  
  27.         return -1;  
  28.     }  
  29.       
  30.     while(left <= right)     --------------------------------------->注意条件  
  31.     {  
  32.         printf("left = %d, right = %d\n", left, right);  
  33.         mid = (left + right) >> 1;                              /*更好的写法是 mid = left + ((right - left) >> 1)*/  
  34.         printf("mid = %d, array[mid] = %d\n", mid, array[mid]);  
  35.         if(array[mid] < key)   
  36.         {  
  37.             left = mid + 1;  
  38.         }  
  39.         else if(array[mid] > key)  
  40.         {  
  41.             right = mid - 1;  
  42.         }     
  43.         else  
  44.         {  
  45.             return mid;  
  46.         }  
  47.     }  
  48.     return -1;  
  49. }  
  50. int main()  
  51. {  
  52.     int tmp[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};  
  53.     int num = 0;  
  54.     int i = 0;  
  55.     int ret = -1;  
  56.     printf("tmp array:");  
  57.     for(i = 0; i < ARRAY_LEN(tmp); i++)  
  58.     {  
  59.         printf(" %d", tmp[i]);  
  60.     }  
  61.     printf("\n");  
  62.     if(-1 == is_sort_asc(tmp, ARRAY_LEN(tmp)))  
  63.     {  
  64.         printf("tmp is not sort by asc\n");  
  65.         return -1;  
  66.     }  
  67.   
  68.     num = 1;  
  69.     ret = binary_search(tmp, 0, ARRAY_LEN(tmp) - 1, num);  
  70.     if(-1 == ret)  
  71.     {  
  72.         printf("can not find the num %d\n", num);  
  73.     }  
  74.     else  
  75.     {  
  76.         printf("find key = %d in tmp[%d]\n", num, ret);  
  77.     }  
  78.     printf("\n");  
  79.     return 0;  
  80. }  

2)二分查找返回key(可能有重复)第一次出现的下标,如无return -1

  1. int binary_search(int array[], int left, int right, int key)  
  2. {  
  3.     int mid = 0;  
  4.     if(right <= 0)  
  5.     {  
  6.         return -1;  
  7.     }  
  8.       
  9.     while(left <= right)  
  10.     {  
  11.         printf("left = %d, right = %d\n", left, right);  
  12.         mid = (left + right) >> 1;  
  13.         printf("mid = %d, array[mid] = %d\n", mid, array[mid]);  
  14.         if(array[mid] < key)   
  15.         {  
  16.             left = mid + 1;  
  17.         }  
  18.         else if(array[mid] > key)  
  19.         {  
  20.             right = mid - 1;  
  21.         }     
  22.         else  
  23.         {  
  24.             while(mid >= 1) --------------------------->注意条件  
  25.             {  
  26.                 if(array[mid] == array[mid-1])  
  27.                 {  
  28.                     mid -= 1;  
  29.                 }  
  30.                 else  
  31.                 {  
  32.                     break;  
  33.                 }  
  34.             }  
  35.             return mid;  
  36.         }  
  37.     }  
  38.     return -1;  
  39. }  

4)二分查找返回刚好小于key的元素下标,如无return -1

  1. int binary_search(int array[], int left, int right, int key)  
  2. {  
  3.     int mid = 0;  
  4.     if(right <= 0)  
  5.     {  
  6.         return -1;  
  7.     }  
  8.       
  9.     while(left <= right)  
  10.     {  
  11.         printf("left = %d, right = %d\n", left, right);  
  12.         mid = (left + right) >> 1;  
  13.         printf("mid = %d, array[mid] = %d\n", mid, array[mid]);  
  14.         if(array[mid] < key)   
  15.         {  
  16.             left = mid + 1;  
  17.         }  
  18.         else if(array[mid] > key)  
  19.         {  
  20.             right = mid - 1;  
  21.         }     
  22.         else  
  23.         {  
  24.             while(mid >= 1) --------------------------->注意条件  
  25.             {  
  26.                 if(array[mid] == array[mid-1])  
  27.                 {  
  28.                     mid -= 1;  
  29.                 }  
  30.                 else  
  31.                 {  
  32.                     break;  
  33.                 }  
  34.             }  
  35.             return mid - 1; /*查找到是第一个元素 直接找不到小于它的索引*/  
  36.         }  
  37.     }  
  38.     return -1;  
  39. }  

任意组合这几种条件, 欢迎高手拍砖。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值