補間検索

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)