• C语言二分查找法(指针和数组实现)


    直接上程序:

    /*
     * 编写一个函数,对一个已排序的整数表执行二分查找。
     * 函数的输入包括各异指向表头的指针,表中的元素个数,以及待查找的数值。
     * 函数的输出时一个指向满足查找要求的元素的指针,当未查找到要求的数值时,输出一个NULL指针
     * 用两个版本实现,一个用的是数组小标,第二个用的是指针
     * 他们均采用了不对称边界
     * 
    Copyright (c) 2012 LiMing
    Author:        LiMing
    2012-06-21
    referenced C Traps and Pitfaills Chinese Edition
    Page 132-137
     * 
     * 查找的元素为x,数组下表是k,开始时0 <= k < n
     * 接下来缩小范围lo <= k < hi,
     * if lo equals hi, we can justify the element "x" is not in the array
     
     * */
    #include <stdio.h>
    
    int array[] = 
    {    
        0,1,2,3,4,5,6,7
    };
    
    int *bsearch_01(int *t, int n, int x);
    
    int *bsearch_01(int *t, int n, int x)
    {
        int lo = 0;
        int hi = n;
        
        while(lo < hi)
        {
            //int mid = (hi + lo) / 2;
            int mid = (hi + lo) >> 1;
            
            if(x < t[mid])
                hi = mid;
            else if(x > t[mid])
                lo = mid + 1;
            else
                return t + mid;        
        }
        return NULL;
    }
    
    int *bsearch_02(int *t, int n, int x);
    
    int *bsearch_02(int *t, int n, int x)
    {
        int lo = 0;
        int hi = n;
        
        while(lo < hi)
        {
            //int mid = (hi + lo) / 2;
            int mid = (hi + lo) >> 1;
            int *p = t + mid;        //用指针变量p存储t+mid的值,这样就不需要每次都重新计算
            
            if(x < *p)
                hi = mid;
            else if(x > *p)
                lo = mid + 1;
            else
                return p;        
        }
        return NULL;
    }
    
    
    //进一步减少寻址运算
    /*
     * Suppose we want to reduce address arithmetic still further 
     * by using pointers instead of subscripts throughout the program.
     * 
     * */
    int *bsearch_03(int *t, int n, int x);
    
    int *bsearch_03(int *t, int n, int x)
    {
        int *lo = t;
        int *hi = t + n;
        
        while(lo < hi)
        {
            //int mid = (hi + lo) / 2;
            int *mid = lo + ((hi - lo) >> 1);
            
            if(x < *mid)
                hi = mid;
            else if(x > *mid)
                lo = mid + 1;
            else
                return mid;    
        }
        return NULL;
    }
    
    /*
     * The resulting program looks somewhat neater because of the symmetry
     * */
    int *bsearch_04(int *t, int n, int x);
    
    int *bsearch_04(int *t, int n, int x)
    {
        int lo = 0;
        int hi = n - 1;
        
        while(lo <= hi)
        {
            //int mid = (hi + lo) / 2;
            int mid = (hi + lo) >> 1;
            
            if(x < t[mid])
                hi = mid - 1;
            else if(x > t[mid])
                lo = mid + 1;
            else
                return t + mid;    
        }
        return NULL;
    }
    
    int main(int argc, char **argv)
    {
        int * ret = NULL;
        int *ret2 = NULL;
        int *ret3 = NULL;
        int *ret4 = NULL;
        
        ret = bsearch_01(array, 8, 3);
        ret2 = bsearch_02(array, 8, 6);
        ret3 = bsearch_03(array, 8, 4);
        ret4 = bsearch_04(array, 8, 2);
        printf("The result is %d\n", *ret);
        printf("The result is %d\n", *ret2);
        printf("The result is %d\n", *ret3);
        printf("The result is %d\n", *ret4);
        
        printf("hello world\n");
        return 0;
    }

    请各位网友指点,参考《c陷阱和缺陷》

  • 相关阅读:
    JS——switch case
    JS——“==”与“===”
    C#——枚举格式转换与比较
    XML——读与写
    SQl基本操作——try catch
    JS——indexOf replace search
    C#——数据库的访问
    SQL基本操作——存储过程
    C#——设置开机启动
    C#——计时器的操作
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/2558597.html
Copyright © 2020-2023  润新知