开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,[点击查看活动详情]
查找算法,排序算法,除了要讨论算法本身的好坏之外,还要讨论数据本身的分布情况。有些数据是随机分布的,方差大。
根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素。
1,顺序查找
2,二分查找
3,插值查找
4,斐波那契查找
5,数表查找
6,分块查找
7,哈希查找
顺序查找
线性查找,属于无序查找算法
开始端——>顺序扫描——>与定值相比较——>相等,成功。不相等,失败。
适合于存储结构为顺序存储或链接存储的线性表。
时间复杂度为O(n);
顺序查找代码
public class LinearSearch{
public static void main(String[] args){
int[] arr={3,9,1,4,5,2,6,8,7};
int key=8;
int index = linearSearch(arr,key);
System.out.println("index = "+index);
}
private static int linearSearch(int[] arr,int key){
for(int i=0;i<arr.length;i++){
if(arr[i]==key){
return i;
}
}
return -1;
}
}
二分查找
折半查找,属于有序查找算法。
定植与中间结点关键字比较——>相等,则成功,不等——>定植与子表比较,递归进行——>结束。
前提:元素是有序的。
时间复杂度为O(log2n).
适用于静态查找表。不适用频繁执行插入或删除操作的数据集。\
代码
迭代法
public class BinarySearch{
public static void main(String[] args){
int[] arr={1,2,3,4,5,6,7,8,9};
int key=8;
int index=binarySearch(arr,key);//角标
System.out.println("index = "+index);
}
private static int binarySearch(int[] arr,int key){
int low = 0;
int high=arr.length-1;
int mid=(low+hige)/2;
while(arr[mid]!=key){
if(arr[mid]>key){
high=mid-1;
}else if(arr[mid]<key){
low=mid+1;
}
if(low>high){
return -1;
}
mid=(low+high)/2;
}
return mid;
}
}
这里类似于循环
递归法
int index=binarySearch(arr,key,0,arr.length-1);
System.out.println("index = "+index);
private static int binarySearch(int[] arr,int key,int low,int high){
if(low>high){
return -1;
}
int mid=(low+high)/2;
if(arr[mid]==key){
return mid;
}
if(key<arr[mid]){
return binarySearch(arr,key,low,mid-1);
}else{
return binarySearch(arr,key,mid-1,high);
}
}
类似于分治(大问题化为小问题)。
计算式:mid=low+1/2*(high-low),避免相加导致整型溢出。
插值查找
类似于二分查找。适用于分布均匀(方差)的查找表。
计算式:mid=low+(key-a[low])/(a[high]-a[low])*(high-low)
时间复杂度:O(log2(log2n)).log2(log2n)<log2n\
代码
public class InterpolationSearch{
public static void main(String[] args){
int[] arr={1,5,12,21,30,32,55,68,80,89,90,99};
int key = 30;
int index = interpolationSearch(arr,key,0,arr.length-1);
System.out.println("index = "+index);
}
private static int interpolationSearch(int[] arr,int key,int low,int high){
if(low>high){
return -1;
}
int mid=low+(int)(1.0*(key-arr[low])/(arr[high]-arr[low])*(high-low));
System.out.println("mid = "+mid);
if(mid<low||mid>high){
return -1;
}
if(arr[mid]==key){
return mid;
}else if(arr[mid]>key){
return interpolationSearch(arr,key,low,mid-1);
}else{
return interpolationSearch(arr,key,mid+1,high);
}
}
}
斐波那契查找
是在二分查找的基础上根据斐波那契数列进行分割的。
是区间中单峰函数的搜索技术。
黄金比例:1:0.618,1.618:1。随着斐波那契的递增,前后两数的比值接近0.618.
代码
public class FibonacciSearch{
public static void main(String[] args){
int[] arr={1,2,3,4,5,6,7,8,9};
int key=8;
int index = fibonacciSearch(arr,key);
System.out.println("index = "+index);
}
private static int fibonacciSearch(int[] arr,int key){
int[] f=getFibonacci();
int low = 0;
int high = arr.length-1;
int mid=0;
int k=0;
while(high>f[k]-1){
k++;
}
int[] temp = Arrays.copyOf(arr,f[k]);
for(int i=high+1;i<temp.length;i++){
temp[i]=arr[high];
}
while(low<=high){
mid=low+f[k-1]-1;
if(key<tem[mid]){
high=mid-1;
k-=1;
}else if(key>temp[mid]){
low=mid+1;
k-=2;
}else{
if(mid<=high){
return mid;
}else{
return high;
}
}
}
return -1;
}
private static int[] getFibonacci(){
int f = new int[20];
f[0]=1;
f[1]=1;
for(int i =2;i<f.length.length;i++){
f[i]=f[i-1]+f[i-2];
}
return f;
}
}