今天我们来说一说查找算法,这也是面试中常问的问题。查找算法主要分为7大类,分别为:顺序查找算法、二分查找算法、插值查找算法、斐波那契查找算法、树表查找算法、分块查找算法、哈希查找算法。共七类算法。
顺序查找算法:
又称线性的查找算法,它是无序的查找算法。它就是利用一次for循环,对所在的数组进行遍历一次,用参考目标元素与数组中的每一个元素去比较。如果查找到直接返回数组的下标位置,否则直到遍历结束时还没有找到就返回-1。
顺序查找适合于存储结构为顺序存储或链接存储的线性表。
时间复杂度:
查找成功时的平均查找长度:(1 + 2 + 3 + 4 + 5 + ... + n -1 + n)/ n = ( n + 1) / 2;
当查找不成功时的查找长度为:(n + 1)即需要比较 n + 1次;
所以时间复杂度为:O(n);
Coding:
public int lineSearch(int searchKey, int arrs[], int n){
for(int i = 0 ; i < n; i++){
if(arrs[i] == searchKey){
return i;
}
}
return -1;
}
二分查找算法:
又称折半查找算法,它的前提是数组必须是有序的。在有序的数组中取中间值作为比较对象,若给定值与中间值相等则查找成功;若给定值小于中间值,则在中间值的左半区继续查找;若给定值大于中间值,则在中间值的右半区继续查找。不断重复上面的步骤,直到查找成功或者查找失败为止。
时间复杂度:
最坏的情况下需要查找log2(n+1),且期望的时间复杂度为O(logn);
Coding:
public int binSearch(int value, int arrs[], int n){
int ins = 0;
int low = 0;
int pow = n;
while(true){
ins = ( low + pow) / 2;
if(arrs[ins] == value){
return ins;
}else if(low > pow){
return -1;
}else{
if(arrs[ins] < value){
low = ins + 1;
}else{
pow = ins - 1;
}
}
}
}
插值查找算法:
精华在于利用斐波那契数列的黄金分割的原理实现的。在海量数据的情况下,查找效率优于折半查找,虽然其时间复杂度也为O(logn)
public static int interpolationSearch(int nums[], int value){
int low = 0, mid, high = nums.length - 1;
while(low <= high){
//与二分查找的区别点,在mid的选择
mid = low + (high-low)*(value - nums[low]) / (nums[high] - nums[low]);
if(nums[mid] == value){
return mid;
}
if(nums[mid] > value){
high = mid - 1;
}
if(nums[mid] < value){
low = mid + 1;
}
}
return -1;
}