折半查找的实现(C语言)

折半查找又称二分查找,仅使用于有序的顺序表。基本思想是:

将给定值与表中中间位置的元素比较,若相等则查找成功,返回该元素的存储位置;若不等则所需查找的元素只能在中间元素以外的前半部分或后半部分。在缩小的范围内重复进行同样的查找直到找到为止,或确定表中没有所需要查找的元素,返回查找失败的信息。

要获得有序的顺序表,可以使用qsort来排序,简要介绍使用方法

#include <stdlib.h>
void qsort(void *buf,size_t num,size_t size,int (*compare)(const void *,const void *));
//buf:要排序数组的起始地址,也可以是指针,申请了一块连续的堆空间
//num:数组中元素的个数
//size:数组中每个元素所占用的空间大小
//compare:比较规则,需要我们传递一个函数名,这个函数由我们自己编写,返回值必须是int类型,形参是两个void类型指针,这个函数是qsort内部调用的,相当于我们传递一种行为给qsort

折半查找的流程是:

  • 初始化顺序表为随机10个元素;
  • 使用qsort进行排序并打印;
  • 输入要查找的元素值到变量key中;
  • 通过二分查找找对应key值,并输出找到或未找到信息。

需要注意的是,虽然复用了顺序查找的部分代码,但折半查找并不需要使用哨兵,注意细节之处。

下面练习:实现折半查找,即自建一个顺序表并排序后实现折半查找。

1. 定义
//折半查找(只适用于顺序表),又称二分查找
typedef int ElemType;
typedef struct {
    ElemType *elem;
    int TableLen;//存储动态数组里元素的个数
}SSTable;
2. 顺序表初始化
//顺序表随机初始化10个元素
void ST_Init(SSTable &ST,int len){
    //顺序查找时使用了哨兵,此处实现时不需要使用哨兵
    ST.TableLen=len;
    ST.elem=(ElemType*)malloc(sizeof(ElemType)*ST.TableLen);
    int i;
    srand(time(NULL));//随机数生成
    for(i=0;i<ST.TableLen;i++){//第0个是哨兵,所以从1随机
        ST.elem[i]=rand()%100;//随机生成的数都在0-99之间
    }
}
3. 打印顺序表
//打印顺序表
void ST_print(SSTable ST){
    int i;
    for (i = 0; i<ST.TableLen ; i++) {
        printf("%3d",ST.elem[i]);
    }
    printf("\n");
}
4. 折半查找
//二分查找,时间复杂度log n
int BinarySearch(SSTable L,ElemType key){
    int low=0;
    int high=L.TableLen-1;
    int mid;
    while(low<=high){//可以让mid既能取到low,也能取到high
        mid=(low+high)/2;
        if(key>L.elem[mid]){//如果目标大于中位数
            low=mid+1;
        }else if(key<L.elem[mid]){
            high=mid-1;
        }else{
            return mid;//等于key就找到了
        }
    }
    return -1;
}
5. 排序实现
//函数名中存储的是函数的入口地址,也是一个指针,是函数指针类型
//left和right指针指向数组中的任意两个元素的地址
//qsort规定如果left指针指向的值大于right指针指向的值,返回正值,小于返回负值,等于返回0
int compare(const void *left,const void *right){
    return *(ElemType *)left-*(ElemType *)right;//从小到大排序
    //return *(ElemType*)right-*(ElemType*)left;//从大到小排序
}
6. 主函数
int main() {
    SSTable ST;
    ST_Init(ST,10);
    ST_print(ST);//打印顺序表中元素
    qsort(ST.elem,ST.TableLen, sizeof(ElemType),compare);//qsort实现的是快速排序
    ST_print(ST);//再次打印
    ElemType key;
    printf("input search key:");
    scanf("%d",&key);
    int pos;
    pos=BinarySearch(ST,key);
    if(pos!=-1){
        printf("BinarySearch find key %d\n",pos);
    } else{
        printf("BinarySearch don't find key\n");
    }
    return 0;
}
7. 测试

最后,1024程序员节快乐~

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多多想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值