插值查找(Java)
插值查找,有序表的一种查找方式。插值查找是根据查找关键字与查找表中最大最小记录关键字比较后的查找方法。插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。
适用条件: 采用顺序存储结构的有序表
重要公式:mid=left+(right-left)*(value-arr[left]) / (arr[right]-arr[left])
优点:对于数据量较大,数值分布均匀时,调用次数相对较少,速度较快
代码实现
无相同字符
public class Insertsort {
public static void main(String[] args) {
int arr[]= {2,4,5,8,11,24,34};
int Index=insertsearch(arr,0,arr.length-1,11);
System.out.print("插值查找结果为:");
if(Index==-1) {
System.out.println("没有该元素");
}
System.out.print(Index);
}
public static int insertsearch(int []arr,int left,int right,int value) {
if(left>right||value<arr[0]||value>arr[arr.length-1]) {
return -1;
}
int mid=left+(right-left)*(value-arr[left])/(arr[right]-arr[left]);
int index=arr[mid];
if(value>index) {//向右递归
return insertsearch(arr,mid+1,right,value);
}else if(value<index) {//向左递归
return insertsearch(arr,left,mid-1,value);
}else {
return mid;
}
}
}
运行结果
插值查找结果为:4
算法改进
有相同字符
import java.util.ArrayList;
import java.util.List;
public class Insertsort {
public static void main(String[] args) {
int arr[]= {2,4,4,5,8,11,11,24,34};
List<Integer> Index=insertsearch(arr,0,arr.length-1,4);
System.out.print("");
System.out.println("插值查找,该元素的下标分别为:"+Index);
}
public static List<Integer> insertsearch(int []arr,int left,int right,int value) {
if(left>right||value<arr[0]||value>arr[arr.length-1]) {
return new ArrayList<Integer>();
}
int mid=left+(right-left)*(value-arr[left])/(arr[right]-arr[left]);
int index=arr[mid];
if(value>index) {//向右递归
return insertsearch(arr,mid+1,right,value);
}else if(value<index) {//向左递归
return insertsearch(arr,left,mid-1,value);
}else {
List<Integer> indexlist=new ArrayList<Integer>();
int temp=mid-1;//向左扫描
while(true) {
if(temp<0||arr[temp]!=value) {
break;
}
indexlist.add(temp);//如果有相同查找元素,则加入
temp-=1;//temp左移,判断是否还有相同的元素
}
indexlist.add(mid);
temp=mid+1;//向右扫描
while(true) {
if(temp>arr.length-1||arr[temp]!=value) {
break;
}
indexlist.add(temp);//如果有相同查找元素,则加入
temp+=1;//temp右移,
}
return indexlist;
}
}
}
插值查找,该元素的下标分别为:[1, 2]