常用查找算法
程序员文章站
2022-07-12 14:51:00
...
查找算法可分为两种:无序查找和有序查找,顾名思义,无序查找就是查找数列中的数是无序的,有序查找要求所查找数列是已经按照一定的规律排好序了,常见算法中大多都是无序查找。下面一一介绍几种常见的查找算法。
1. 顺序查找
- 类型:无序查找。
-
基本思想:
从数据列中的一段开始(通常是起始位置),顺序扫描,依次比较所扫描数和目标值,如果相等则查找成功。若扫描结束仍没有找到那么就查找失败。 - 复杂度分析:
平均查找长度 | 时间复杂度 |
---|---|
(n+1)/2 | O(n) |
- 示例代码:
public static int sequenceSearch(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i;
}
}
return -1;
}
2. 二分查找(折半查找)
- 类型:有序查找。
-
基本思想:
用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。 - 复杂度分析:
平均查找长度 | 时间复杂度 |
---|---|
log2(n+1) | O(log2n) |
- 示例代码:
//二分查找 非递归
public static int binarySearch(int[] arr, int target) {
SortUtil.quickSort(arr, 0, arr.length - 1);
int low = 0, high = arr.length - 1, mid;
while (low <= high) {
if (target == arr[low]) {
return low;
}
if (target == arr[high]) {
return high;
}
mid = (low + high) / 2;
if (target == arr[mid]) {
return mid;
} else if (target > arr[mid]) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
3. 插值查找
- 类型:有序查找。
-
基本思想:
是二分查找的一种优化,将查找点改进为自适应选择以提高查找效率。(将mid = (low + high) /2
取中值的取法换成了mid = low + (target - arr[low]) / (arr[high] - arr[low] * (high - low))
) - 时间复杂度分析: O(log2(log2n))
- 示例代码:
public static int insertionSearch(int[] arr, int target, int low, int high) {
if (low <= high) {
if (target == arr[low]) {
return low;
}
if (target == arr[high]) {
return high;
}
int mid = low + (target - arr[low]) / (arr[high] - arr[low] * (high - low));
if (target == arr[mid]) {
return mid;
} else if (target < arr[mid]) {
return insertionSearch(arr, target, low, mid - 1);
} else {
return insertionSearch(arr, target, mid + 1, high);
}
}
return -1;
}
3. 斐波那契查找
- 类型:有序查找。
- 斐波那契数列:相信很多同学都早已有所耳闻,即1,1,2,3,5,8,13...,从第三个数开始,后面的数都等于前两个数之和,而斐波那契查找就是利用的斐波那契数列来实现查找的。
-
基本思想:
同样的是,它是二分查找的一个优化,它是根据斐波那契序列的特点对有序表进行分割。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;然后需要装填一个长度为n的新数组,且mid = low + fib(k - 1) - 1
,k为fib(k) - 1
刚好大于原数组长度的那个值。
开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种
1)相等,mid位置的元素即为所求
2)>,low=mid+1,k-=2;
说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。
3)<,high=mid-1,k-=1。
说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。
-
时间复杂度:O(log2n)。
由于时间有些仓促,下面的查找算法尚未理解透彻,暂时只记录基本思想,示例代码后面有空补上 = =。
4. 树表查找
顾名思义,就是将所查找数列构建成一颗树,其中最常见的是构建成一颗二叉查找树(左子节点的值均小于父节点的值,右子节点的值均大于父节点的值),然后通过遍历比较得出查找结果。
上一篇: Java多态性
下一篇: java 常用查找算法