进行二分搜索的数组要求是有序的,二分搜索通过持续跟踪数组中包含元素t的范围来解决问题。一开始,这个范围是整个数组,然后通过将t与数组的中间项进行比较并抛弃一半的范围来缩小范围。该过程持续进行,直到在数组中找到t或确定包含t的范围为空时为止,在有n个元素的表中,二分搜索大约需要执行log2n次比较操作。
1. 最基础的二分查找
下面的的例子为升序情况的二分查找的情况。
示例:如有已排序数组有8个元素如下查找元素x = 5;
1  5  6  7  9  10  12 44
将数组分为两个子段(0+7)/2 = 3: 1  5  6  7  9  10  12 44
比较array[3] = 7与x = 5的大小由于数组为升序:
(1)若分段点元素大于x,则不用查找分段点以后的元素;
(2)若分段点元素小于x,则不用查找分段前之前的元素;
(3)若分段点元素等于x表示已找到该元素,返回。
array[3]比x大,则查找array[4]之前的元素,将array[4]之前的看作一个子数组继续进行二分操作。
语法:result=search_bin(int *t,int k,int n);
参数:
t[]:
待查找数组
k:
查找关键字
n:
数组元素个数
返回值:
如果k在t[]中存在,输出i:t[i]=k,否则输出-1
注意:
 数组元素从0开始存储
 
要求查找数组是有序升序序列
源程序:
 
 
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索 int search_bin(int *t,int k,int n)
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索        int low=0,high=n-1,mid;
二分搜索及改进(1)_二分搜索        while (low<=high)
二分搜索及改进(1)_二分搜索                {
二分搜索及改进(1)_二分搜索                mid=(low+high)/2;
二分搜索及改进(1)_二分搜索                if (k==t[mid]) return mid;
二分搜索及改进(1)_二分搜索                else if (k<t[mid]) high=mid-1;
二分搜索及改进(1)_二分搜索                else low=mid+1;
二分搜索及改进(1)_二分搜索                }
二分搜索及改进(1)_二分搜索        return -1;
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
 
2.改进二分查找--若查找的元素出现多次查找第一次出现的位置
我们可以从第一次得代码中知道,上述代码不能确定查找到得元素的位置为第一次出现的位置。怎么确定查找的元素在该序列中出现的是第一次呢,我们举一个例:
数组:1  2  3  3  3  3  3  5 ;8个元素,查找值为3的元素。
将数组分为两个子段(0+7)/2 = 3: 1  2  3  3  3  3  3  5 
此时已查找到3,一种简单的实现方法可以在从该位置开始向前搜索,找到直到不等于3的时候就停止,这个时候找到3的位置就是第一次出现的位置,同理我们也可以用这种方法找到最后出现的3的位置。
语法:result=search_bin(int *t,int k,int n);
参数:
t[]:
待查找数组
k:
查找关键字
n:
数组元素个数
返回值:
如果k在t[]中存在,输出i,i为k在t[]中第一次出现的位置:t[i]=k,否则输出-1
注意:
 数组元素从0开始存储
 
要求查找数组是有序升序序列
源程序:
 
 
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索 int search_bin(int *t,int k,int n)
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索        int low=0,high=n-1,mid;
二分搜索及改进(1)_二分搜索        while (low<=high)
二分搜索及改进(1)_二分搜索                {
二分搜索及改进(1)_二分搜索                mid=(low+high)/2;
二分搜索及改进(1)_二分搜索                if (k==t[mid])    
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索        {
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索             while(t[mid] != k)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索             {
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                    mid--;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索             }
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                return mid+1;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索        }                
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索        else if (k<t[mid]) high=mid-1;
二分搜索及改进(1)_二分搜索                else low=mid+1;
二分搜索及改进(1)_二分搜索                }
二分搜索及改进(1)_二分搜索        return -1;
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
 
我们通过上面的代码也许可以知道,这样实现确实很简单,但是这样效率确实降低了,如果有一个极端的例子,即一个数组里面的元素全部相同,且我们要查找的元素就是该数组的元素此时在查找第一个出现位置的时候就比较消耗时间,这里我们可以深入一点,继续利用分治的方法查找它第一次出现的位置。
示例:数组:1  2  3  3  3  3  3  5 ;8个元素,查找值为3的元素。
将数组分为两个子段(0+7)/2 = 3: 1  2  3  3  3  3  3  5 
在查找到元素后记录该位置flag ,由于搜索的是第一次出现的位置,所以 应该搜索左子数组,调整搜索上界为mid-1,即为high=2;
在此范围内继续进行二分查找,实际上就是在查找到元素的时候并不停止搜索,而是继续搜索直到搜索子数组不存在。
语法:result=search_bin(int *t,int k,int n);
参数:
t[]:
待查找数组
k:
查找关键字
n:
数组元素个数
返回值:
如果k在t[]中存在,输出i,i为k在t[]中第一次出现的位置:t[i]=k,否则输出-1
注意:
 数组元素从0开始存储
 
要求查找数组是有序升序序列
源程序:
 
 
二分搜索及改进(1)_二分搜索int search_bin(int *t,int k,int n)
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索        int low=0,high=n-1,mid;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int    flag = -1;
二分搜索及改进(1)_二分搜索        while (low<=high)
二分搜索及改进(1)_二分搜索                {
二分搜索及改进(1)_二分搜索                mid=(low+high)/2;
二分搜索及改进(1)_二分搜索                if (k==t[mid])    
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索        {
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                flag = mid;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                high = mid-1;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                //如果查找最后一次出现的位置
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索                //low = mid + 1;;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索        }
二分搜索及改进(1)_二分搜索                else if (k<t[mid]) high=mid-1;
二分搜索及改进(1)_二分搜索                else low=mid+1;
二分搜索及改进(1)_二分搜索                }
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索if(flag == -1)
二分搜索及改进(1)_二分搜索        return -1;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索else
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索return flag;
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
 
         另外一种实现该改进的方法是按照《编程珠玑》第9.3节中所讲的进行改进,程序如下:
二分搜索及改进(1)_二分搜索int search_bin(int *t,int k,int n){    
二分搜索及改进(1)_二分搜索    
二分搜索及改进(1)_二分搜索 int low=-1,high=n,mid;
二分搜索及改进(1)_二分搜索    
二分搜索及改进(1)_二分搜索 while (low+1!=high)        
二分搜索及改进(1)_二分搜索 {        
二分搜索及改进(1)_二分搜索    mid=(low+high)/2;            
二分搜索及改进(1)_二分搜索    if (t[mid]<k)    
二分搜索及改进(1)_二分搜索     low=mid;        
二分搜索及改进(1)_二分搜索    else            
二分搜索及改进(1)_二分搜索     high=mid;
二分搜索及改进(1)_二分搜索 }
二分搜索及改进(1)_二分搜索    
二分搜索及改进(1)_二分搜索 if(high>=n||t[high]!=k)    
二分搜索及改进(1)_二分搜索    return -1;
二分搜索及改进(1)_二分搜索 else    
二分搜索及改进(1)_二分搜索    return high;    
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
测试程序:
二分搜索及改进(1)_二分搜索#include <stdio.h>
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索#include <stdlib.h>
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索#include <math.h>
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索#include<time.h>
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int     cmp     (     const     void     *a     ,     const     void     *b     )            
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{            
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索return     *(int     *)a     -     *(int     *)b;            
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}    
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索//在此加入二分搜索的程序search_bin
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int main(int argc, char **argv)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int array[100];
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int i,j;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int p[2];
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索int key;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索srand(time(0));
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索for(i = 0; i< 100; i++)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索array[i] = rand()%100;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索qsort(array,100,sizeof(array[0]),cmp);
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索for(i = 0; i< 10; i++)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索for(j=0; j<10; j++)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索printf(" %d ", array[i*10+j]);
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索printf("\n");
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索while(1)
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索{
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索printf("key : ");
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索scanf("%d", &key);
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索p[0] = search_bin(array,key,100);
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索printf("%d \n",p[0]);
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索return 0;
二分搜索及改进(1)_二分搜索
二分搜索及改进(1)_二分搜索}
二分搜索及改进(1)_二分搜索