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;
}

时间: 2024-11-24 23:54:17

C语言二分查找法(指针和数组实现)的相关文章

【C/C++学院】(3)二维数组/二分查找法/指针/模块注射

1.二维数组 二维数组可以当做一个一维数组, 每一个元素又是一个一维数组. #include <stdio.h> #include <stdlib.h> void main() { int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("%d,%d,%d,%x,%x &

【C/C++学院】0723-32位与64位/调戏窗口程序/数据分离算法/内存检索/二分查找法/myVC

[送给在路上的程序员] 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. 32位与64位 地址与内存的关系 4G = 4*1024M = 4*1024*1024k = 4*1024*1024*1024 Byte字节 = 2

C#使用二分查找法判断指定字符的方法_C#教程

本文实例讲述了C#使用二分查找法判断指定字符的方法.分享给大家供大家参考,具体如下: private int sort_init(ref string[] chars, string str) //数组初始化 { string[] temp = str.Split(' '); //temp. chars = new string[temp.Count()]; int ndx = 0; int last_empty_positon = 0; foreach (string ch in temp)

php 二分查找法算法详解

一.概念:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 二.代

javascript实现二分查找法实现代码_javascript技巧

一般二分都用到int[]型上.....在js中可能会更灵活的用到a-z上,或者用到拼音...或者用到...... 不过值得深思的一个问题是,如果为了实现对拼音之类的二分查找.而经过如下流程是否值得: 1.对拼音排序,貌似代码量不小吧. 2.然后再二分查找.这又需要识别拼音的大小,貌似也不算太小吧. 找到结果的速度快了,可是别人下你的js文件速度慢多了,呵呵,到底舍弃谁. 下面的代码甚至可以10亿条,一样会很快找到,可是用遍例的模式创建那个数组...所以还是别尝试了.只是给个思路,下次我再来发个j

C语言二分查找算法及实现代码_C 语言

二分査找也称折半査找,其优点是查找速度快,缺点是要求所要査找的数据必须是有序序列.该算法的基本思想是将所要査找的序列的中间位置的数据与所要査找的元素进行比较,如果相等,则表示査找成功,否则将以该位置为基准将所要査找的序列分为左右两部分.接下来根据所要査找序列的升降序规律及中间元素与所查找元素的大小关系,来选择所要査找元素可能存在的那部分序列,对其采用同样的方法进行査找,直至能够确定所要查找的元素是否存在,具体的使用方法可通过下面的代码具体了解. #include <stdio.h> binar

使用javascipt---实现二分查找法_基础知识

复制代码 代码如下: <html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><script type="text/javascript">     //window.alert(Math.floor(5.7)); //向下取整 输出5     //二分查找法 数组必须是有序的     functio

精典算法之二分查找法

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.  二分查找法是已经排好顺序的集合,要从集合的中间开始查找,如果这个项小于我们要查找的数,则这个项前边的所有数都小于我们要查找的对象 就无需再浪费时间去查在前边的数查找;如果搜寻的数天于我们要查找的对象那么这个数的后边的数都大于我们要查找的对象,则后边的数我们也不用再去查找了. 下边我会用c#和c++两种语言给出代码 c#二分查找代码

JAVA二分查找法

问题描述 引用原文:http://blog.csdn.net/middlekingt/article/details/8446590问题1:为什么要inthigh=nums.length-1;如果inthigh=nums.length;可以吗? 解决方案 解决方案二:可以,但你自己要控制好边界.解决方案三:请问控制边界是什么意思呢?intmid=(low+high)/2:他是这样表示中间值的,那我直接inthigh=nums.length:intmid=high/2:这样行吗?中间值就等于数组长