二分查找法
介绍和思路
二分查找法,顾名思义就是一半一半的找,但是使用此查找方法有一个前提,就是必须是有序数组。
思路是:先找到中间值,与要查找的值作比较,如果中间值大于要找的值,则向左半区查找,若小于则向右半区查找,若相等则返回下标,以此类推。没找到值的条件是查找区间长度<=0也就是查找左下标大于右下标。
代码
//二分查找法
public static ArrayList binarySearch(int[] arr,int left,int right,int finalVal) {
//如果左>右说明没找到,返回空
if(finalVal<arr[0]||finalVal>arr[arr.length-1]||left>right) {
return new ArrayList<Integer>();
}
int mid=(left+right)/2;
if(finalVal > arr[mid]) {
//左递归
return binarySearch(arr, mid+1, right, finalVal);
}else if(finalVal < arr[mid]) {
//右递归
return binarySearch(arr, left, mid-1, finalVal);
}else {
//找到数了,但可能不止一个,都加入list集合中
ArrayList<Integer> list = new ArrayList<>();
int le=mid-1,ri=mid+1;
list.add(mid);
while(le>=left&&arr[le]==finalVal) {
list.add(le--);
}
while(ri<=right&&arr[ri]==finalVal) {
list.add(ri++);
}
return list;
}
}
插值查找法
介绍和思路
- 插值查找算法类似于二分查找,不同的是插值查找每次从自适应mid处开始查找。
- 将折半查找中的求mid 索引的公式 , low 表示左边索引left, high表示右边索引right.key 就是前面我们讲的 findVal
修改mid的定义,使得查找更加精准
low就是left,high就是right
代码
与二分查找法基本一致,把int mid=(left+right)/2;
代码改成int mid=left + (right-left) * (finalVal - arr[left]) / (arr[right] - arr[left]);
修改mid的意义,二分查找的代码就成了插值查找法的代码
注意事项
- 对于数据量较大,关键字分布比较均匀的查找表来说,采用插值查找, 速度较快.
- 关键字分布不均匀的情况下,该方法不一定比折半查找要好