基本思想:
插值查找是二分查找的一种优化,不同之处在于插值查找中mid为自适应更新
区别于二分查找中:
插值查找中:
可根据需要查找的值自适应的计算出大致的mid,效率更高
需要注意的是,若目标元素在待查找数组中不存在,即目标元素过大或过小,可能会造成计算出的mid过大或过小,进而导致数组越界问题,故需要首先判断目标元素是否在数组范围内
对于目标元素在数组中存在多个,查找方法与二分查找相同,不再赘述
代码实现:
//插值查找
public int insertValueSearch(int value) {
return insertValueSearch(0, array.length - 1, value);
}
public int insertValueSearch(int left, int right, int value) {
if (left > right || value < array[0] || value > array[array.length - 1]) {
return -1;
}
int mid = left + (right - left) * (value - array[left]) / (array[right] - array[left]);
if (value < array[mid]) {
return insertValueSearch(left, mid - 1, value);
} else if (value > array[mid]) {
return insertValueSearch(mid + 1, right, value);
} else {
return mid;
}
}
//插值查找(可查找多个相同元素)
public HashSet<Integer> superInsertValueSearch(int value) {
return superInsertValueSearch(0, array.length - 1, value);
}
public HashSet<Integer> superInsertValueSearch(int left, int right, int value) {
if (left > right || value < array[0] || value > array[array.length - 1]) {
return new HashSet<Integer>();
}
int mid = left + (right - left) * (value - array[left]) / (array[right] - array[left]);
if (value < array[mid]) {
return superInsertValueSearch(left, mid - 1, value);
} else if (value > array[mid]) {
return superInsertValueSearch(mid + 1, right, value);
} else {
HashSet<Integer> hashSet = new HashSet<>();
int temp = mid - 1;
while (temp >= 0 && array[temp] == value) {
hashSet.add(temp);
temp--;
}
hashSet.add(mid);
temp = mid + 1;
while (temp <= array.length - 1 && array[temp] == value) {
hashSet.add(temp);
temp++;
}
return hashSet;
}
}
时间复杂度:O(loglogn)