今天总结了有序表查找常用的三种算法与大家分享。
1.折半查找
折半查找又称二分查找,它的基本思想是:在有序表中,取中间记录作为比较对象,若相等则查找成功;若给定值小于中间记录的关键字,则在中间记录左半区继续查找,若给定值大于中间值,则在又半区寻找,不断重复以上过程。
算法代码(java版)
int binarySearch(int[] a,int key){ int low,high,mid; low = 0; high = a.length-1; while(low<=high){ mid = (low+high)/2; if(key<a[mid]) high = mid-1; else if(key>a[mid]) low = mid+1; else return mid; } return -1; }
时间复杂度为O(logn) ,显然好于顺序查找的时间复杂度O(n)。
2.插值查找
折半查找在某些情况下也明显不足,在大小分布均匀的数组中查找,折半查找可能就会浪费很多时间。
折半查找中 mid=(low+high)/2 = low+(high-low)/2;
算法科学家们将此等式加以改进于是 将1/2替换成(key-a[low])/(a[high]-a[low]),于是就有了mid = low+(high-low)*(key-a[low])/(a[high]-a[low]);
算法代码(java版)
public int insertSearch(int[] a,int key){ int low,high,mid; low = 0; high = a.length-1; while(low<=high){ mid = low+(high-low)*(key-a[low])/(a[high]-a[low]); if(key<a[mid]) high = mid-1; else if(key>a[mid]) low = mid+1; else return mid; } return -1; }
插值查找的时间复杂度也是O(logn),但是对于关键字分布均匀的查找表来说,平均性能比折半查找好得多。
3.斐波那契查找
利用黄金分割进行查找
其核心思想是当 key=a[mid]时查找成功,当key<a[mid]时,新的范围是第low个到地mid-1个,此时范围个数为F[k-1]-1个,当key>a[mid]时,新的范围是第low个到地mid+1个,此时范围个数为F[k-2]-1个。
算法实例(java版)
public int FibonacciSearch(int[] a,int key){ int low,high,mid,k=0; low=0; high=a.length; while(a.length>fibonacci(k)-1) k++; for(int i=a.length;i<fibonacci(k)-1;i++) a[i] = a[a.length-1]; while(low<=high){ mid = low+fibonacci(k-1)-1; if(key<a[mid]){ high = mid-1; k=k-1; } else if(key>a[mid]){ low=mid+1; k=k-2; } else{ if(mid<=a.length) return mid; else return a.length; } } return -1; } public int fibonacci(int n){ return n>2?fibonacci(n-1)+fibonacci(n-2):1; }
斐波那契查找的时间复杂度也是O(logn),但就平均性能来说,优于折半查找。果是最坏的情况,比如这里key=1,那么始终都处于左侧在查找,则查找效率低于折半查找。
时间: 2024-08-29 14:15:28