logo

補間検索

n 個の均一に分散された値のソートされた配列 arr[] が与えられた場合、配列内の特定の要素 x を検索する関数を作成します。 
線形検索は O(n) 時間で要素を見つけます ジャンプ検索 O(n) 時間がかかり、 二分探索 O(log n) 時間がかかります。 
補間検索は、 二分探索 たとえば、ソートされた配列内の値が均一に分布している場合です。内挿は、既知のデータ ポイントの離散セットの範囲内に新しいデータ ポイントを構築します。二分探索では常に中央の要素がチェックされます。一方、補間検索では、検索対象のキーの値に応じて異なる場所に移動する場合があります。例えばキーの値が最後の要素に近い場合、補間検索は末尾側に向かって検索を開始する可能性が高くなります。
検索する位置を見つけるには、次の式を使用します。 

// 式の考え方は、pos のより高い値を返すことです
// 検索対象の要素が arr[hi] に近い場合。そして
// arr[lo]に近づくほど値が小さくなる



arr[] ==> 要素を検索する必要がある配列

x ==> 検索対象の要素

lo ==> arr[] の開始インデックス



こんにちは ==> arr[] の終了インデックス

= の後 +               

さまざまな補間方法があり、その 1 つが線形補間として知られています。線形補間では、(x1y1) と (x2y2) として想定される 2 つのデータ ポイントが使用され、式は次のようになります。 at point(xy)



このアルゴリズムは、辞書で単語を検索するのと同じように機能します。補間検索アルゴリズムは、二分探索アルゴリズムを改善します。  値を見つけるための公式は次のとおりです: K = >K は、検索空間を狭めるために使用される定数です。二分探索の場合、この定数の値は K=(low+high)/2 です。

  

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 lohi 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 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
<script> // Javascript program to implement Interpolation Search // If x is present in arr[0..n-1] then returns // index of it else returns -1. function interpolationSearch(arr lo hi x){  let 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 + Math.floor(((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 let arr = [10 12 13 16 18 19 20 21   22 23 24 33 35 42 47]; let n = arr.length; // Element to be searched let x = 18 let index = interpolationSearch(arr 0 n - 1 x); // If element was found if (index != -1){  document.write(`Element found at index ${index}`) }else{  document.write('Element not found'); } // This code is contributed by _saurabh_jaiswal </script> 
PHP
 // PHP program to implement $erpolation search // with recursion // If x is present in arr[0..n-1] then returns // index of it else returns -1. function interpolationSearch($arr $lo $hi $x) { // 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 = (int)($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 // Array of items on which search will // be conducted. $arr = array(10 12 13 16 18 19 20 21 22 23 24 33 35 42 47); $n = sizeof($arr); $x = 47; // Element to be searched $index = interpolationSearch($arr 0 $n - 1 $x); // If element was found if ($index != -1) echo 'Element found at index '.$index; else echo 'Element not found.'; return 0; #This code is contributed by Susobhan Akhuli ?> 

出力
Element found at index 4

時間計算量: O(ログ2(ログ2平均的な場合は n))、最悪の場合は O(n) 
補助スペースの複雑さ: ○(1)

別のアプローチ:-

これは、内挿検索の反復アプローチです。

  • ステップ1: ループ内で、プローブ位置式を使用して 'pos' の値を計算します。 
  • ステップ2: 一致する場合は、項目のインデックスを返して終了します。 
  • ステップ3: 項目が arr[pos] より小さい場合は、左側のサブ配列のプローブ位置を計算します。それ以外の場合は、右側の部分配列で同じことを計算します。 
  • ステップ4: 一致するものが見つかるか、サブ配列がゼロになるまで繰り返します。

以下はアルゴリズムの実装です。 

C++
// C++ program to implement interpolation search by using iteration approach #include   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 
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;  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.');  } } 
Python
# Python equivalent of above C++ code  # Python program to implement interpolation search by using iteration approach def interpolationSearch(arr n x): # Find indexes of two corners  low = 0 high = (n - 1) # Since array is sorted an element present  # in array must be in range defined by corner  while low <= high and x >= arr[low] and x <= arr[high]: if low == high: if arr[low] == x: return low; return -1; # Probing the position with keeping  # uniform distribution in mind.  pos = int(low + (((float(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 lower part  else: high = pos - 1; return -1 # Main function if __name__ == '__main__': # Array of items on whighch search will  # be conducted. arr = [10 12 13 16 18 19 20 21 22 23 24 33 35 42 47] n = len(arr) x = 18 # Element to be searched index = interpolationSearch(arr n x) # If element was found if index != -1: print ('Element found at index'index) else: print ('Element not found') 
C#
// 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 
JavaScript
// JavaScript program to implement interpolation search by using iteration approach function interpolationSearch(arr n x) { // Find indexes of two corners let low = 0; let 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.  let pos = Math.floor(low + (((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 lower part  else {  high = pos - 1;  } } return -1; } // Main function let arr = [10 12 13 16 18 19 20 21 22 23 24 33 35 42 47]; let n = arr.length; let x = 18; // Element to be searched let index = interpolationSearch(arr n x); // If element was found if (index != -1) { console.log('Element found at index' index); } else { console.log('Element not found'); } 

出力
Element found at index 4

時間計算量: 平均的な場合は O(log2(log2 n))、最悪の場合は O(n) 
補助スペースの複雑さ: ○(1)