查找算法(3)--Interpolation search--插值查找


1. 插值查找
  (1)說明

    在介紹插值查找之前,首先考慮一個新問題,為什么上述算法一定要是折半,而不是折四分之一或者折更多呢?
    打個比方,在英文字典里面查“apple”,你下意識翻開字典是翻前面的書頁還是后面的書頁呢?如果再讓你查“zoo”,你又怎么查?很顯然,這里你絕對不會是從中間開始查起,而是有一定目的的往前或往后翻。
    同樣的,比如要在取值范圍1 ~ 10000 之間 100 個元素從小到大均勻分布的數組中查找5, 我們自然會考慮從數組下標較小的開始查找。
    經過以上分析,折半查找這種查找方式,不是自適應的(也就是說是傻瓜式的)。二分查找中查找點計算如下:

      mid=(low+high)/2, 即mid=low+1/2*(high-low);
    通過類比,我們可以將查找的點改進為如下:

      mid=low+(key-a[low])/(a[high]-a[low])*(high-low),
    也就是將上述的比例參數1/2改進為自適應的,根據關鍵字在整個有序表中所處的位置,讓mid值的變化更靠近關鍵字key,這樣也就間接地減少了比較次數。

 

  (2)基本思想:
    基於二分查找算法,將查找點的選擇改進為自適應選擇,可以提高查找效率。當然,差值查找也屬於有序查找。
  注:對於表長較大,而關鍵字分布又比較均勻的查找表來說,插值查找算法的平均性能比折半查找要好的多。反之,數組中如果分布非常不均勻,那么插值查找未必是很合適的選擇。
  (3)復雜度分析
    查找成功或者失敗的時間復雜度均為O(log2(log2n))。
2.代碼

public static int insertionSearch(int a[], int value, int low, int high) {
  int mid = low + (value - a[low]) / (a[high] - a[low]) * (high - low);
  if (a[mid] == value)
    return mid;
  if (a[mid] > value)
    return insertionSearch(a, value, low, mid - 1);
  if (a[mid] < value)
    return insertionSearch(a, value, mid + 1, high);
  return -1;
}
public static void main(String[] args) {
  int[] a = {27,38,49,50,65,76,197,213};//必須是有序的
  int num = insertionSearch(a, 213,0,a.length-1);
  System.out.println("數組的下標是:" + num);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM