• 查找算法——插值查找法


    一、介绍 

            插值查找法是二分查找的改进版,同样的它需要查找的数据也是有序的,它是按照数据位置的分布,利用公式预测数据所在的位置,再以二分法的方式渐渐逼近。使用这种查找方法需要数据是平均分布的,而且每一项数据的差距相当接近或有一定的距离比例,也就是说每两项数据的差值的大小差别不能太大或者每两项数据的之间的差值都有一定比例的,数据之间分布是均匀的,因为这种方式用要查找的数据值与区间最小值的差与区间范围的比值来确定数据的大概范围,所以就限定了要查找的数据的所需条件。

    插值查找法的公式为:

    其中key是要查找数据,data[high]、data[Low]是剩余待查找记录中的最大值和最小值。

    查找的步骤如下:

    1.确实要查找的数据是有序的或者将要查找的数据排序。

    2.令low =0,high= 数据的长度 -1。

    3.当low < high 时,重复 步骤4和5。

    4.令

    5.若 key < keyMid 且 high != Mid -1,则令high =  Mid -1。

    6.若key = keyMid, 表示成功找到该值。

    7.若key>keyMid,且low!=Mid -1,则令low=Mid+1;

    演示如下:

     二、代码实现:

    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. public class InterpolationLookUpArithmetic : MonoBehaviour
    4. {
    5. List<int> data;
    6. [SerializeField]
    7. int dataLength = 100;
    8. int needData = 0;
    9. private void Start()
    10. {
    11. data = new List<int>(dataLength);
    12. InitData(dataLength);
    13. InterpolationLookUp(needData);
    14. }
    15. void InitData(int datalen)
    16. {
    17. for (int i = 0; i < datalen; i++)
    18. {
    19. data.Add(i);
    20. if (i > 40 && needData == 0)
    21. needData = i + Random.Range(-10,10);
    22. }
    23. }
    24. void InterpolationLookUp(int val)
    25. {
    26. int low, high, mid;
    27. low = 0;
    28. high = data.Count - 1;
    29. if (val < data[low] || val > data[high])
    30. {
    31. Debug.LogError("数据不在要查找的数据范围内。");
    32. return;
    33. }
    34. while (low <= high)
    35. {
    36. mid = low + (val - data[low]) / (data[high] - data[low]) * (high - low);
    37. //首先要确定这个mid的值是否是在可用范围内
    38. if (mid > high || mid < low)
    39. {
    40. Debug.LogError("mid超出范围");
    41. return;
    42. }
    43. //然后要确定这时的val和data[low]、data[high]的大小关系,确定val是否在区间范围内
    44. if (val < data[low] && val < data[high])
    45. {
    46. Debug.LogError("数值未达到数据范围");
    47. return;
    48. }
    49. else if (val > data[low] && val > data[high])
    50. {
    51. Debug.LogError("数值超出数据范围");
    52. return;
    53. }
    54. //以下就是类似二分法的步骤
    55. if (val == data[mid])
    56. {
    57. Debug.Log("找到该值");
    58. return;
    59. }
    60. else if (val < data[mid])
    61. {
    62. high = mid - 1;
    63. }
    64. else if (val > data[mid])
    65. {
    66. low = mid + 1;
    67. }
    68. }
    69. Debug.LogError("没有查找到数据");
    70. }
    71. }

    参考书籍:

    清华大学出版社-图书详情-《图解数据结构--使用C#》 (tsinghua.edu.cn)

  • 相关阅读:
    【C++】C++11部分特性
    ES6异步编程解决方案——async、Generator、Promise
    Qt的Q_UNUSED()函数的功能
    go并发操作且限制数量
    ​标签体系、用户画像、用户分群的区别?​
    C#上位机系列(1)—项目的建立
    Linux内核有什么之内存管理子系统有什么第一回 —— 引言
    conda常用命令合集
    Spring拦截器和过滤器的区别及详解
    【计算机网络五】运输层
  • 原文地址:https://blog.csdn.net/weixin_50702814/article/details/133698353