首页 > 编程语言 >c# 插值搜索-迭代与递归(Interpolation Search)

c# 插值搜索-迭代与递归(Interpolation Search)

时间:2024-04-02 11:00:24浏览次数:21  
标签:Search arr c# lo pos int hi low Interpolation

        给定一个由 n 个均匀分布值 arr[] 组成的排序数组,编写一个函数来搜索数组中的特定元素 x。 
        线性搜索需要 O(n) 时间找到元素,跳转搜索需要 O(? n) 时间,二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进,其中排序数组中的值是均匀分布的。

        插值在一组离散的已知数据点的范围内构造新的数据点。二分查找总是到中间元素去检查。

        另一方面,插值搜索可以根据正在搜索的键的值去不同的位置。例如,如果键的值更接近最后一个元素,则插值搜索很可能从末尾侧开始搜索。为了找到要搜索的位置,它使用以下公式。 

// 公式的思想是
当要搜索的元素更接近arr[hi]时,返回较高的pos值。 
// 当接近 arr[lo] 时值更小
arr[] ==> 需要查找元素的数组
x ==> 要搜索的元素
lo ==> arr[] 中的起始索引
hi ==> arr[] 中的结束索引

        有许多不同的插值方法,其中一种称为线性插值。线性插值采用两个数据点,我们假设为 (x1,y1) 和 (x2,y2),公式为:在点 (x,y) 处。
        该算法的工作原理类似于我们在字典中搜索单词。插值搜索算法改进了二分搜索算法。查找值的公式为:K = 数据-低/高-低。
        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)
从 (3) x - arr[lo] = m * (pos - lo) 减去 eqxn (2) 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# program to implement 
// interpolation search
using System;
 
class GFG{
 
// If x is present in 
// arr[0..n-1], then 
// returns index of it, 
// else returns -1.
static 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 + (((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 
public static void Main() 
{
     
    // Array of items on which search will 
    // be conducted. 
    int []arr = new int[]{ 10, 12, 13, 16, 18, 
                           19, 20, 21, 22, 23, 
                           24, 33, 35, 42, 47 };
                            
    // Element to be searched                       
    int x = 18; 
    int n = arr.Length;
    int index = interpolationSearch(arr, 0, n - 1, x);
     
    // If element was found
    if (index != -1)
        Console.WriteLine("Element found at index " + 
                           index);
    else
        Console.WriteLine("Element not found.");
}
}
 
// This code is contributed by equbalzeeshan 

输出
在索引 4 处找到的元素
时间复杂度:平均情况为O(log 2 (log 2 n)),最坏情况为 O(n) 
辅助空间复杂度: O(1) 

另一种方法:
这是插值搜索的迭代方法。
步骤1:在循环中,使用探针位置公式计算“pos”的值。 
步骤2:如果匹配,则返回该项的索引,并退出。 
步骤3:如果该项小于arr[pos],则计算左子数组的探针位置。否则,在右侧子数组中计算相同的值。 
步骤4:重复直到找到匹配项或子数组减少到零。

下面是算法的实现:  

// C# program to implement interpolation search by using
// iteration approach
using System;
 
class Program
{
    // Interpolation Search function
    static int InterpolationSearch(int[] arr, int n, int x)
    {
        int low = 0;
        int high = n - 1;
   
        while (low <= high && x >= arr[low] && x <= arr[high]) 
        {
            if (low == high) 
            {
                if (arr[low] == x) 
                    return low; 
                return -1; 
            }
   
            int pos = low + (int)(((float)(high - low) / (arr[high] - arr[low])) * (x - arr[low]));
   
            if (arr[pos] == x) 
                return pos; 
   
            if (arr[pos] < x) 
                low = pos + 1; 
   
            else
                high = pos - 1; 
        }
   
        return -1;
    }
   
    // Main function
    static void Main(string[] args)
    {
        int[] arr = {10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47};
        int n = arr.Length;
   
        int x = 18;
        int index = InterpolationSearch(arr, n, x);
   
        if (index != -1) 
            Console.WriteLine("Element found at index " + index);
        else
            Console.WriteLine("Element not found");
    }
}
 
// This code is contributed by Susobhan Akhuli 

输出
在索引 4 处找到的元素
时间复杂度:平均情况为 O(log2(log2 n)),最坏情况为 O(n) 
辅助空间复杂度: O(1)  

标签:Search,arr,c#,lo,pos,int,hi,low,Interpolation
From: https://blog.csdn.net/hefeng_aspnet/article/details/137069975

相关文章

  • vue3从精通到入门9:计算属性computed
    在Vue3中,computed 是一个用于创建计算属性的工具,它基于组件的响应式依赖进行复杂的计算,并返回一个新的响应式引用。计算属性是Vue的一个核心概念,它提供了一种声明式的方式来执行基于其依赖的响应式数据的计算。computed使用:计算属性与常规属性类似,但是它们是基于它们......
  • stm32cubeide 调试非 0x08000000 地址程序配置
    使用stm32cubeide调试非0x08000000,我们需要一些配置.ld链接脚本条件编译目前如果要修改程序的启动地址需要修改两个地方system_stm32f103xx.c中的VECT_TAB_OFFSET,可通过宏定义开启或者关闭.ld链接脚本,可通过宏进行条件编译,也可以直接修改ld,创建不同的链接脚本文件,创建......
  • BSL: Understanding and Improving Softmax Loss for Recommendation
    目录概符号说明SoftmaxlossBilateralSoftmaxloss(BSL)代码WuJ.,ChenJ.,WuJ.,ShiW.,ZhangJ.andWangX.BSL:UnderstandingandImprovingSoftmaxLossforRecommendation.ICDE,2024.概作者'发现'在协同过滤中,Softmaxloss会比BCE/BPR损失效果好很多,......
  • ARM架构银河麒麟使用笔记-下载docker软件包及所有依赖包并在离线环境下安装
    ARM架构银河麒麟使用笔记-下载docker软件包及所有依赖包并在离线环境下安装arm银河麒麟aptdocker目的是在arm架构的银河麒麟操作系统V10中安装docker。一、给虚拟机创建快照1.创建qemu-imgsnapshot-cEmptyKylinrootfs.qcow22.查看qemu-imgsnapshot-lrootfs......
  • [MRCTF2020]PYWebsite
    [MRCTF2020]PYWebsite查看源代码发现验证成功后跳转flag页面<script>functionenc(code){hash=hex_md5(code);returnhash;}functionvalidate(){varcode=document.getElementById("vcode").value;if(code!="......
  • C# .NET6 WebAPI JWT身份验证服务
    自定义扩展类usingMicrosoft.AspNetCore.Authentication;usingMicrosoft.AspNetCore.Authentication.JwtBearer;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.AspNetCore.Mvc.ModelBinding;usingSystem.Text.Json;namespaceDemo{///<summary>///......
  • Android TV Recyclerview长按或连续按键,焦点丢失(或者焦点跳跃)
    原因分析RecyclerView设置适配器后,将数据填充进去,并不会将所有item的view都创建出来,一般只会创建一个屏幕的Item,当长按或者快速按下键时,Recyclerview来不及创建即将获取焦点的view,导致焦点丢失解决方法有两种思路:(1)控制按键速度 这里有两种具体实现策略:一种是记录......
  • Ubuntu安装docker
    官网卸载系统docker,防止冲突forpkgindocker.iodocker-docdocker-composedocker-compose-v2podman-dockercontainerdrunc;dosudoapt-getremove$pkg;done卸载请参照docker卸载设置docker的apt仓库sudoapt-getupdatesudoapt-getinstallca-certificat......
  • static 关键字2----不是原创
    在学习volatile关键字时,在此重温下C语言的其他关键字static。这个关键字可以说到处都在用,但是能否详细说清楚这个static应该怎么用,什么场景用,怎么用合适?当你写下static的时候,是否考虑了真的需要用static吗?在前面笔记中也有学习了static,但明显感觉得出来,当时对static的理解不到......
  • CleanMyMac X2024专为苹果Mac系统设计的垃圾清理工具
    CleanMyMac作为一款专为Mac系统设计的垃圾清理工具,以其强大的清理能力、简便的操作方式以及卓越的系统兼容性,受到了众多Mac用户的青睐。以下是对这款软件功能的详细介绍:CleanMyMacX2024全新版下载如下:https://wm.makeding.com/iclk/?zoneid=49983一、高效彻底的清理效果......