二分法有序数组搜索
我爱撸码,撸码使我感到快乐!
大家好,我是Counter。
今天来记录下,有序数组搜索,最实用的的方法,它的时间复杂度为O(nlogN)。
自定义函数,两个形参,第一个是要搜索的数组,第二个是要搜索的元素。如果这个元素存在在这个数组里的话,则返回这个元素所在的索引值,否则的话返回-1.
具体效果如下(假设一个有序数组):
搜索3这个元素是否在这个有序数组里,是的话则返回它所在的索引值,结果发现,是存在的。那么再搜索11是否在这个有序数组里,结果返回是-1,是不存在的。
好了,代码给出:
// 假设有序数组 var arr = [1, 2, 3, 4, 5, 6, 9, 10]; // 数组二分法,第一个参数为传入的数组,第二个参数是,要搜索这个数组里的元素,如果存在则返回这个元素的索引,如果没有则返回-1 function indexOf(arr, val) { // 向下取整,确保更能接近数组的中间元素 var i = Math.floor(arr.length / 2); // 判断传入的元素是否等于这个数组的中间元素,如果相对那么直接返回这个元素的索引 if ( val === arr[i] ) { return i; } // 如果数组的长度为1,并且前面的判断不符合,那么直接返回-1,提高性能,少做一次判断 if ( arr.length == 1 ) { return -1; } // 如果传入的元素小于这个数组的中间值,那么直接返回再次调用,indexOf,再寻找前半部分的元素,递归。 else if ( val < arr[i] ) { return indexOf(arr.slice(0, i), val); } // 如果传入的参数比数组中间的元素大,那么再次调用indexOf,在寻找后半部分的元素,递归,注意此处,不能直接返回了,因为裁剪后的子数组,索引从0开始。如果没有找到的话就等于-1,如果查找到的话,那么索引值等于当前子数组的索引值加上 i+1(前面的二分法后一位的索引) else if ( val > arr[i] ) { var s = indexOf(arr.slice(i+1), val); return s == -1 ? s : s + i + 1; } }
养成记录的习惯,离前端大神又近一步,加油,然后就是后端,最后是全栈,fighting!!!