查找算法之内插搜寻法

news/2024/6/3 0:21:55 标签: 算法, 数据结构, 动态规划

给定一个由n个均匀分布的值组成的排序数组arr[],编写一个函数来搜索数组中特定的元素x。

线性搜索需要O(n)个时间,跳转搜索需要O(√n)个时间,二分搜索需要O(log n)个时间。

插值搜索是对实例的二进制搜索的改进,其中排序数组中的值是均匀分布的。插值在已知数据点的离散集范围内构造新的数据点。二分查找总是到中间的元素进行检查。另一方面,插值搜索可以根据被搜索键的值去不同的位置。例如,如果键的值更接近最后一个元素,插值搜索可能会从结束端开始搜索。

算法公式

为了找到要搜索的位置,使用以下公式。

//公式的思想是返回更高的pos值

//当要搜索的元素接近arr[hi]时。和

//当接近arr[lo]时更小的值

有许多不同的插值方法,其中一个被称为线性插值。线性插值取(x1,y1)和(x2,y2)两个数据点,公式为:在点(x,y)处。

这个算法的工作方式是我们在字典中搜索单词。插值搜索算法改进了二分搜索算法。求值的公式是 K = data-low/high-low.。

K是一个常数,用来缩小搜索空间。在二分搜索的情况下,这个常数的值是:K=(low+high)/2.

pos的公式可以推导如下。

假设数组的元素是线性分布的。

直线一般方程:y = m*x + c。

Y是数组中的值,x是它的下标。

现在把lo hi和x的值代入方程

arr[hi] = m*hi+c ----(1)

arr[lo] = m*lo+c ----(2)

x = m*pos + c ----(3)

m = (arr[hi] - arr[lo] )/ (hi - lo)

subtracting eqxn (2) from (3)

x - arr[lo] = m * (pos - lo)

lo + (x - arr[lo])/m = pos

pos = lo + (x - arr[lo]) *(hi - lo)/(arr[hi] - arr[lo])

算法

内插搜寻算法的其余部分除了上面的分区逻辑外是相同的。

步骤1:在循环中,使用上面给出的公式计算“pos”的值。

步骤2:如果匹配,返回该项的索引,并退出。

步骤3:如果项目小于arr[pos],计算左子数组的探测位置。否则,在右子数组中进行相同的计算。

步骤4:重复操作,直到找到匹配项或子数组归零。

下面是算法的C代码递归方法实现。

// C program to implement interpolation search
// with recursion
#include <stdio.h>

// If x is present in arr[0..n-1], then returns
// index of it, else returns -1.
int interpolationSearch(int arr[], int lo, int hi, int x)
{
    int pos;
    // Since array is sorted, an element present
    // in array must be in range defined by corner
    if (lo <= hi && x >= arr[lo] && x <= arr[hi]) {
        // Probing the position with keeping
        // uniform distribution in mind.
        pos = lo
            + (((double)(hi - lo) / (arr[hi] - arr[lo]))
                * (x - arr[lo]));

        // Condition of target found
        if (arr[pos] == x)
            return pos;

        // If x is larger, x is in right sub array
        if (arr[pos] < x)
            return interpolationSearch(arr, pos + 1, hi, x);

        // If x is smaller, x is in left sub array
        if (arr[pos] > x)
            return interpolationSearch(arr, lo, pos - 1, x);
    }
    return -1;
}

// Driver Code
int main()
{
    // Array of items on which search will
    // be conducted.
    int arr[] = { 10, 12, 13, 16, 18, 19, 20, 21,
                22, 23, 24, 33, 35, 42, 47 };
    int n = sizeof(arr) / sizeof(arr[0]);

    int x = 18; // Element to be searched
    int index = interpolationSearch(arr, 0, n - 1, x);

    // If element was found
    if (index != -1)
        printf("Element found at index %d", index);
    else
        printf("Element not found.");
    return 0;
}

输出

Element found at index 4

下面是算法的C++代码递归方法实现。

// C++ program to implement interpolation search by using iteration approach
#include<bits/stdc++.h>
using namespace std;

int interpolationSearch(int arr[], int n, int x)
{
    // Find indexes of two corners
    int low = 0, high = (n - 1);
    // Since array is sorted, an element present
    // in array must be in range defined by corner
    while (low <= high && x >= arr[low] && x <= arr[high])
    {
        if (low == high)
        {if (arr[low] == x) return low;
        return -1;
        }
        // Probing the position with keeping
        // uniform distribution in mind.
        int pos = low + (((double)(high - low) /
            (arr[high] - arr[low])) * (x - arr[low]));

        // Condition of target found
        if (arr[pos] == x)
            return pos;
        // If x is larger, x is in upper part
        if (arr[pos] < x)
            low = pos + 1;
        // If x is smaller, x is in the lower part
        else
            high = pos - 1;
    }
    return -1;
}

// Main function
int main()
{
    // Array of items on whighch search will
    // be conducted.
    int arr[] = {10, 12, 13, 16, 18, 19, 20, 21,
                22, 23, 24, 33, 35, 42, 47};
    int n = sizeof(arr)/sizeof(arr[0]);

    int x = 18; // Element to be searched
    int index = interpolationSearch(arr, n, x);

    // If element was found
    if (index != -1)
        cout << "Element found at index " << index;
    else
        cout << "Element not found.";
    return 0;
}
//this code contributed by Ajay Singh


http://www.niftyadmin.cn/n/164598.html

相关文章

假如用CSS来逆向推理视觉设计空间

最近几个月都在忙乎自己的产品&#xff0c;活生生体验了一把需求-设计-前端开发集成式累成狗的节奏&#xff1b;但&#xff0c;作为自从离开学校后基本没怎么敲代码的半吊子选手&#xff0c;通过这次的自力更生&#xff0c;仿佛在coding的黑暗中找到了design的光明&#xff0c;…

RK3399 UBUNTU 程序开机自启动

创建autostart目录mkdir ~/.config/autostart创建待启动的程序vi ~/.config/autostart/test.desktop内容如下&#xff1a;[Desktop Entry]Version1.0NametestExec/home/xxx/textStartupNotifyfalseNoDisplayfalseTypeApplicationHiddenfalse附&#xff1a;双声卡时设置默认声卡…

MPC 101:安全多方计算与多方签名

1982年,姚期智先生,图灵奖获得者,在他的论文中提出了安全多方计算这一重要概念。为了形象地介绍安全多方计算这个概念,他提出了著名的「百万富翁问题」。 两个百万富翁在街头碰面,为了争一口气,希望 PK 出谁更加富有,同时希望能让对方不知道自己资产的真实数额。 这篇论…

【Leetcode】4. Median of Two Sorted Arrays 双有序数组找中位数

一、 描述 给两个有序数组&#xff0c;长度分别为m和n&#xff0c;找他们的中位数&#xff0c;要求时间复杂度O(log(mn))。 二、分析 咋一看是很简单的题&#xff0c;但是坑了我两个星期。其中既有两年没做题的因素在&#xff0c;但是更重要的是本就菜逼的我更加菜了。这让我…

Redis 不仅仅是单线程

文章目录 一、redis 后台线程?二、后台线程慢操作(blocking)close_fileaof_fsynclazy_free三、总结本文参考版本 redis6.2 我们常说 redis 是单线程模型,一般是指正常的 请求处理+周期任务。其中: 处理请求包括:包括接收连接、IO监听/读/写以及命令执行。周期任务,如删除…

MAC QT OpenGL 图像 GPUImageAmatorkaFilter

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 转场 零基础 OpenGL ES 学习路线推荐 :…

历史大讲堂:iPhone为啥这么火?苹果系统历史回顾(下)

想必大家都或多或少有手机吧。做个调查&#xff1a;你的手机是什么品牌&#xff1f;你最想要什么品牌&#xff1f;&#xff08;有多个手机的选一个你最喜欢的&#xff09; 好了&#xff0c;不废话了&#xff0c;今天继续唠苹果-手机。今天我会把苹果手机发展和iOS发展混起来讲…

【SSM】MyBatis(三.核⼼配置⽂件详解)

文章目录1.environment2.transactionManager3. dataSource3.1 使用UNPOOLED3.2 使用POOLED3.3 POOLED的一些配置4.properties5.mapper1.environment 两个数据库都有一张名为car的表&#xff1a; mybatis-config.xml <?xml version"1.0" encoding"UTF-8…