二分法有序数组搜索

我爱撸码,撸码使我感到快乐!
大家好,我是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!!!

猜你喜欢

转载自www.cnblogs.com/Counterrr/p/10638714.html
今日推荐