使用 Java 的 DSA - 插值查詢



概述

插值查詢是二分查詢的改良版本。此搜尋演算法使用所需值的探查位置。此演算法要能正常運作,資料集合必須已排序。

插值查詢藉助於計算探查位置的方式查詢特定專案。最初探查位置是集合中中間專案的位置。如果出現匹配,則會返回專案索引。如果中間專案的項大於所需項,則重新計算右方的子陣列的探查位置,否則在左方的子陣列中查詢所需項。此過程還會繼續在子陣列中進行,直到子陣列的大小變為零。

插值查詢的示例為字典查詢,從某個單詞開始,例如從 X 開始進行查詢,我們將在字典的末尾附近進行查詢,從而插入探查位置,依此類推。

演算法

Interpolation Search ( A: array of item, n: total no. of items 
        ,x: item to be searched)
Step 1: Set lowerBound = 0
Step 2: Set upperBound = n - 1
Step 3: if lowerBound  = upperBound or A[lowerBound] = A[upperBound] 
        go to step 12
Step 4: set midPoint = lowerBound + 
        ((upperBound -lowerBound) / (A[upperBound] - A[lowerBound])) 
        * (x - A[lowerBound])
Step 5: if A[midPoint] < x
Step 6: set from = midPoint + 1
Step 7: if A[midPoint] > x
Step 8: set to = midPoint - 1 
Step 9  if A[midPoint] = x go to step 11
Step 10: Go to Step 3
Step 11: Print Element x Found at index midPoint and go to step 13
Step 12: Print element not found
Step 13: Exit

演示程式

package com.tutorialspoint.simplesearch;

import java.util.Arrays;

public class InterpolationSearchDemo {
    
   public static void main(String args[]){
      int[] sourceArray = {1,2,3,4,6,7,9,11,12,14,15,
      16,17,19,33,34,43,45,55,66,76,88};
      System.out.println("Input Array: " +Arrays.toString(sourceArray));
      printline(50);
      // find location of 55 //
      int location = find(sourceArray, 55);
      if(location != -1){
         System.out.println("Element found at location: " +(location+1));
      }else {
         System.out.println("Element not found.");
      }    
   }

   public static int find(int[] intArray, int data){
      int lowerBound = 0;
      int upperBound = intArray.length -1;
      int midPoint = -1;
      int comparisons = 0;      
      int index = -1;
      while(lowerBound <= upperBound){
         System.out.println("Comparison " + (comparisons +1) ) ;
         System.out.println("lowerBound : "+lowerBound  
                           + " , intArray[" + lowerBound+"] = " 
                           + intArray[lowerBound]) ;
         System.out.println("upperBound : "+upperBound  
                           + " , intArray[" + upperBound+"] = " 
                           + intArray[upperBound]) ;
         comparisons++;
         // probe the mid point 
         midPoint = lowerBound + 
         Math.round((float)(upperBound - lowerBound) 
            / (intArray[upperBound] - intArray[lowerBound]) 
            *  (data - intArray[lowerBound]));
         System.out.println("midPoint = "+midPoint);
         // data found 
         if(intArray[midPoint] == data){
		    index = midPoint;
            break;
         }
         else {
            // if data is larger 
            if(intArray[midPoint] < data){
               // data is in upper half 
               lowerBound = midPoint + 1;
            }
            // data is smaller 
            else{           
               // data is in lower half 
               upperBound = midPoint -1;
            }
         }               
      }
      System.out.println("Total comparisons made: " + comparisons);
      return index;
   }
   
   public static void printline(int count){
      for(int i=0;i <count-1;i++){
         System.out.print("=");
      }
      System.out.println("=");
   }
}

如果我們編譯並執行上述程式,則會得到以下結果 -

Input Array: [1 2 3 4 6 7 9 11 12 14 15 16 17 19 33 34 43 45 55 66 ]
==================================================
Comparison 1
lowerBound : 0, intArray[0] = 1
upperBound : 19, intArray[19] = 66
midPoint = 16
Comparison 2
lowerBound : 17, intArray[17] = 45
upperBound : 19, intArray[19] = 66
midPoint = 18
Total comparisons made: 2
Element found at location: 19
廣告