插值查找(比例查找法)

插值查找(比例查找法)

摘要

当我们在使用**折半查找法**的时候,都会有个疑问,为什么一定要用折半,为什么不能折三分之一,四分之一呢?为什么我们不能根据我们查找的数值的不同而制定不同的比例来查找呢?于是,经过算法科学家的努力,插值查找法(按比例查找)诞生了。

首先我们先写出折半查找法的核心语句
mid = (right + left) / 2;
代换为
mid =left+ (right - left) / 2;
算法科学家通过对这个1/2进行改进,得到了下面这个算法
mid = left + (key - a[left]) * (right - left) / (a[right] - a[left]);

	int a[] ={1,3,5,7,9,11,13,15,17,19};

例如我们要在上面这个数据中查找17
mid = 0 + (17-1)*(9-0)/(18) = 8;
仅仅一次我们就可以查找到想要的数据‘
而它这次中直接按照88%左右的效率直接查到了结尾的17,效率一下子就高了很多,如果这里采用的是折半查找法,要查找三次,差距十分明显。
虽然从时间复杂度来看它和折半查找都是O(log n),但是对于表长比较大,数据分布均匀的查找表,它的性能要比折半查找法优秀很多,但是他也不是完全高于折半查找,如果数组中分布数据极度不均匀,它的效率可能会低折半查找法略低。

插值查找

int search(int* p, int number, int under, int top)
{
    //int mind = (under + top) / 2;  //二分法查找    
    //按比例查找(插值查找)
    int mind = under + (number - p[under]) * (top - under) / (p[top] - p[under]);
    if (mind < under || mind > top)
    {
        return 0;
    }
    else if (p[mind] < number)
    {
        return search(p, number, mind + 1, top);
    }
    else if (p[mind] > number)
    {
        return search(p, number, under, mind - 1);
    }
    else return mind+1;
}

测试代码

#include <stdio.h>

int search(int* p, int number, int under, int top)
{
    //int mind = (under + top) / 2;  //二分法查找    
    //按比例查找(插值查找)
    int mind = under + (number - p[under]) * (top - under) / (p[top] - p[under]);
    if (mind < under || mind > top)
    {
        return 0;
    }
    else if (p[mind] < number)
    {
        return search(p, number, mind + 1, top);
    }
    else if (p[mind] > number)
    {
        return search(p, number, under, mind - 1);
    }
    else return mind+1;
}
int main()
{
    int number[] = { 1,3,5,7,9,11,13,15,17,19 };

    int c;
    for (int i = 0; i < 10; i++)
        printf("%4d",number[i]);
    printf("\n请输入你需要查找的数字:");
    scanf_s("%d", &c);
    if (search(number, c, 1, 10))
    {
        printf("你所查找的数字位置为:%d\n", search(number, c, 1, 10));
    }
    else {
        printf("未查找到");
    }
   
    return  0;
}



实验数据

在这里插入图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值