笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
最近在项目中要使用查找算法,正好利用这次机会,把算法再复习一遍,这次是利用跳跃查找算法解决问题。
Jump Search 跳跃搜索算法跟二分查找算法类似,它也是针对有序序列的查找,只是它是通过查找比较少的元素找到目标。当然它需要通过固定的跳跃间隔,这样它相比二分查找效率提高了很多。
例如,假设我们有一个大小为n的数组arr []和要跳跃的大小m。 然后我们搜索索引arr [0],arr [m],arr [2m] ... ..arr [km]等等。 一旦我们找到间隔(arr [km]
我们考虑以下数组:(0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610)。 数组的长度为16.跳跃搜索将以下列步骤找到值55,假设要跳过的大小为4。
步骤1:从索引0跳转到索引4;
步骤2:从索引4跳转到索引8;
步骤3:从索引8跳转到索引16;
步骤4:由于索引16处的元素大于55,因此我们将跳回一步到索引9。
步骤5:从索引9执行线性搜索以获得元素55。
关于跳跃的大小数值确定,在最坏的情况下,我们必须进行n / m跳转,如果最后一个检查值大于要搜索的元素,则我们对线性搜索进行m-1比较。 因此,最坏情况下的比较总数将为((n / m)+ m-1)。 当m =√n时,函数((n / m)+ m-1)的值将为最小值。 因此,最好的步长是m =√n。
我们这次使用java实现,代码如下所示:
// Java program to implement Jump Search.
public class JumpSearch
{
public static int jumpSearch(int[] arr, int x)
{
int n = arr.length;
// Finding block size to be jumped
int step = (int)Math.floor(Math.sqrt(n));
// Finding the block where element is
// present (if it is present)
int prev = 0;
while (arr[Math.min(step, n)-1] < x)
{
prev = step;
step += (int)Math.floor(Math.sqrt(n));
if (prev >= n)
return -1;
}
// Doing a linear search for x in block
// beginning with prev.
while (arr[prev] < x)
{
prev++;
// If we reached next block or end of
// array, element is not present.
if (prev == Math.min(step, n))
return -1;
}
// If element is found
if (arr[prev] == x)
return prev;
return -1;
}
// Driver program to test function
public static void main(String [ ] args)
{
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610};
int x = 55;
// Find the index of 'x' using Jump Search
int index = jumpSearch(arr, x);
// Print the index where 'x' is located
System.out.println("\nNumber " + x +
" is at index " + index);
}
}
运行结果分析:
时间复杂度:O(√n)
辅助空间:O(1)
算法小结:
一、该算法仅适用于有序数组
二、要跳转的最佳大小为O(√n), 这使得跳跃搜索O(√n)的时间复杂度。
三、跳跃搜索的时间复杂度在线性搜索((O(n))和二分查找搜索(O(Log n))之间。
四、二分查找算法相比跳跃搜索更好,但是跳跃搜索有以下优点:跳跃搜索仅遍历一次,而二分查找最多需要O(Log n),考虑要搜索的元素是最小元素或小于 最小的),我们选用Jump Search。