📜  插值搜索

📅  最后修改于: 2021-05-06 19:39:28             🧑  作者: Mango

给定n个均匀分布的值arr []的排序数组,编写一个函数以搜索数组中的特定元素x。
线性搜索以O(n)时间查找元素,跳转搜索以O(√n)时间查找,而二进制搜索则以O(Log n)时间查找。
插值搜索是对二进制搜索的改进,该实例对已排序数组中的值均匀分布的实例进行了搜索。二进制搜索总是转到中间元素进行检查。另一方面,根据要搜索的关键字的值,插值搜索可以转到不同的位置。例如,如果键的值更接近最后一个元素,则插值搜索可能会朝着端侧开始搜索。
为了找到要搜索的位置,它使用以下公式。

// The idea of formula is to return higher value of pos
// when element to be searched is closer to arr[hi]. And
// smaller value when closer to arr[lo]
pos = lo + [ (x-arr[lo])*(hi-lo) / (arr[hi]-arr[Lo]) ]

arr[] ==> Array where elements need to be searched
x     ==> Element to be searched
lo    ==> Starting index in arr[]
hi    ==> Ending index in arr[]

pos的公式可推导如下。

Let's assume that the elements of the array are linearly distributed. 

General equation of line : y = m*x + c.
y is the value in the array and x is its index.

Now putting value of lo,hi and x in the equation
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
#include
using namespace std;
 
// If x is present in arr[0..n-1], then returns
// index of it, else returns -1.
int interpolationSearch(int arr[], int n, int x)
{
    // Find indexes of two corners
    int lo = 0, hi = (n - 1);
 
    // Since array is sorted, an element present
    // in array must be in range defined by corner
    while (lo <= hi && x >= arr[lo] && x <= arr[hi])
    {
        if (lo == hi)
        {
            if (arr[lo] == x) return lo;
            return -1;
        }
        // Probing the position with keeping
        // uniform distribution in mind.
        int 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 upper part
        if (arr[pos] < x)
            lo = pos + 1;
 
        // If x is smaller, x is in the lower part
        else
            hi = pos - 1;
    }
    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, n, x);
 
    // If element was found
    if (index != -1)
        cout << "Element found at index " << index;
    else
        cout << "Element not found.";
    return 0;
}
 
// This code is contributed by Mukul Singh.


C++
// C++ program to implement interpolation
// search with recursion
#include 
using namespace std;
 
// 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]);
 
    // Element to be searched
    int x = 18;
    int index = interpolationSearch(arr, 0, n - 1, x);
 
    // If element was found
    if (index != -1)
        cout << "Element found at index " << index;
    else
        cout << "Element not found.";
 
    return 0;
}
 
// This code is contributed by equbalzeeshan


C
// C program to implement interpolation search
// with recursion
#include 
 
// 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;
}


Java
// Java program to implement interpolation
// search with recursion
import java.util.*;
 
class GFG {
 
    // If x is present in arr[0..n-1], then returns
    // index of it, else returns -1.
    public 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(String[] args)
    {
 
        // 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 = arr.length;
 
        // Element to be searched
        int x = 18;
        int index = interpolationSearch(arr, 0, n - 1, x);
 
        // If element was found
        if (index != -1)
            System.out.println("Element found at index "
                               + index);
        else
            System.out.println("Element not found.");
    }
}
 
// This code is contributed by equbalzeeshan


Python
# Python3 program to implement
# interpolation search
# with recursion
 
# If x is present in arr[0..n-1], then
# returns index of it, else returns -1.
 
 
def interpolationSearch(arr, lo, hi, x):
 
    # Since array is sorted, an element present
    # in array must be in range defined by corner
    if (lo <= hi and x >= arr[lo] and 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 subarray
        if arr[pos] < x:
            return interpolationSearch(arr, pos + 1,
                                       hi, x)
 
        # If x is smaller, x is in left subarray
        if arr[pos] > x:
            return interpolationSearch(arr, lo,
                                       pos - 1, x)
    return -1
 
# Driver code
 
 
# Array of items in which
# search will be conducted
arr = [10, 12, 13, 16, 18, 19, 20,
       21, 22, 23, 24, 33, 35, 42, 47]
n = len(arr)
 
# Element to be searched
x = 18
index = interpolationSearch(arr, 0, n - 1, x)
 
if index != -1:
    print("Element found at index", index)
else:
    print("Element not found")
 
# This code is contributed by Hardik Jain


C#
// 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


Javascript


输出
Element found at index 4