本期目录
一,跳转搜索算法介绍
二,跳转搜索算法代码实现
三,跳转搜索算法总结
四,跳转搜索算法完整代码
此搜索类似于“二分法检索(binary search)”,但不会向前和向后跳转-我们只会向前跳转。请记住,跳转搜索还需要对集合进行排序。
基本思想是通过固定步长跳过或跳过某些元素来代替搜索所有元素来检查更少的元素(与线性搜索相比)。
在“跳转搜索”中,我们sqrt(arraylength)
在前一个间隔中跳转,直到到达一个大于当前元素或数组末尾的元素。每次跳跃时,都会记录上一步。
如果遇到的元素大于要搜索的元素,我们将停止跳跃。然后,我们在上一步和当前步骤之间运行线性搜索。
这使得线性搜索的搜索空间要小得多,因此成为可行的选择。
/**
* 跳转搜索
* @param integers
* @param elementToSearch
* @return
*/
public static int jumpSearch(int[] integers, int elementToSearch) {
int arrayLength = integers.length;
int jumpStep = (int) Math.sqrt(integers.length);
int previousStep = 0;
while (integers[Math.min(jumpStep, arrayLength) - 1] < elementToSearch) {
previousStep = jumpStep;
jumpStep += (int)(Math.sqrt(arrayLength));
if (previousStep >= arrayLength)
return -1;
}
while (integers[previousStep] < elementToSearch) {
previousStep++;
if (previousStep == Math.min(jumpStep, arrayLength))
return -1;
}
if (integers[previousStep] == elementToSearch)
return previousStep;
return -1;
}
我们以jumpstep
数组长度的平方根大小开始,并继续以相同的大小向前跳跃,直到找到一个等于或大于要搜索的元素的元素。
因此,我们首先访问的元素integers[jumpStep]
,然后访问integers[2jumpStep]
,integers[3jumpStep]
依此类推。我们还将先前访问的元素存储在previousStep
变量中。
一旦我们找到一个值,使得integers[previousStep]
< elementToSearch
< integers[jumpStep]
,我们执行之间的线性搜索integers[previousStep]
而integers[jumpStep]
不是元素大于或elementToSearch
。
测试一下:
public static void main(String[] args) {
int index = jumpSearch(new int[]{3, 22, 27, 47, 57, 67, 89, 91, 95, 99}, 67);
print(67, index);
}
结果:
时间复杂度
由于我们sqrt(arraylength)
在每次迭代中都跳过步骤,因此此搜索的时间复杂度为O(sqrt(N))。
空间复杂度
此搜索的空间复杂度为O(1),因为它仅需要一个空间单位即可存储要搜索的元素。
当返回成本很高时,此搜索将用于二进制搜索。当我们很容易向前搜索时使用类似驱动器的旋转介质时会遇到此约束,但多次沿改变方向跳跃成本会非常高。
If you are interested, try it.
public class SearchAlgorithms {
/**
* 跳转搜索
* @param integers
* @param elementToSearch
* @return
*/
public static int jumpSearch(int[] integers, int elementToSearch) {
int arrayLength = integers.length;
int jumpStep = (int) Math.sqrt(integers.length);
int previousStep = 0;
while (integers[Math.min(jumpStep, arrayLength) - 1] < elementToSearch) {
previousStep = jumpStep;
jumpStep += (int)(Math.sqrt(arrayLength));
if (previousStep >= arrayLength)
return -1;
}
while (integers[previousStep] < elementToSearch) {
previousStep++;
if (previousStep == Math.min(jumpStep, arrayLength))
return -1;
}
if (integers[previousStep] == elementToSearch)
return previousStep;
return -1;
}
/**
* 打印方法
* @param elementToSearch
* @param index
*/
public static void print(int elementToSearch, int index) {
if (index == -1){
System.out.println(elementToSearch + " 未找到");
}
else {
System.out.println(elementToSearch + " 在索引处找到: " + index);
}
}
//测试一下
public static void main(String[] args) {
int index = jumpSearch(new int[]{3, 22, 27, 47, 57, 67, 89, 91, 95, 99}, 67);
print(67, index);
}
}