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

1. 插值查找
  (1)說明算法

    在介紹插值查找以前,首先考慮一個新問題,爲何上述算法必定要是折半,而不是折四分之一或者折更多呢?
    打個比方,在英文字典裏面查「apple」,你下意識翻開字典是翻前面的書頁仍是後面的書頁呢?若是再讓你查「zoo」,你又怎麼查?很顯然,這裏你絕對不會是從中間開始查起,而是有必定目的的往前或日後翻。
    一樣的,好比要在取值範圍1 ~ 10000 之間 100 個元素從小到大均勻分佈的數組中查找5, 咱們天然會考慮從數組下標較小的開始查找。
    通過以上分析,折半查找這種查找方式,不是自適應的(也就是說是傻瓜式的)。二分查找中查找點計算以下:數組

      mid=(low+high)/2, 即mid=low+1/2*(high-low);
    經過類比,咱們能夠將查找的點改進爲以下:app

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

 

  (2)基本思想:
    基於二分查找算法,將查找點的選擇改進爲自適應選擇,能夠提升查找效率。固然,差值查找也屬於有序查找。
  注:對於表長較大,而關鍵字分佈又比較均勻的查找表來講,插值查找算法的平均性能比折半查找要好的多。反之,數組中若是分佈很是不均勻,那麼插值查找未必是很合適的選擇。
  (3)複雜度分析
    查找成功或者失敗的時間複雜度均爲O(log2(log2n))。
2.代碼spa

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);
}
相關文章
相關標籤/搜索