前端学习--查找

顺序查找

普通的遍历,穷举法。

/**
 * 查找一个数组中目标值是否存在(顺序查找)
 * @param {*} arr 
 * @param {*} target 
 */
var num = 0;
function inOrderSearch(arr, target){
    for ( var i = 0; i < arr.length; i++){
        num++;
        if ( arr[i] === target){
            return  true;
        }
    
    }
    return  false;

}

二分查找

如果一个序列是一个排序好的序列,则使用二分查找可以极大的缩短查找时间

查找该序列中间未知的数据,步骤:

  1. 相等,找到
  2. 要找的数据较大,则对后续部分的数据做同样的步骤
  3. 要找的数据较小,则对前面部分的数据做同样的步骤
/**
* 二分查找
* @param {*} arr 
* @param {*} target 
*/

function binarySearch(arr,target){
  if (arr.length === 0 || target < arr[0] || target > arr[arr.length - 1])    return false;
  var minIndex = 0;//最小下标
  var maxIndex = arr.length - 1;//最大下标
  while (minIndex <= maxIndex){
      num++;
      var mid = Math.floor((minIndex + maxIndex)/2);//中间下标
      if  (arr[mid] === target){
          return true;
      }else if(arr[mid] > target){
          maxIndex = mid - 1;
      }else{
          minIndex = mid + 1;
      }
  }
  return false;
}

插值查找

插值查找是对二分查找的进一步改进
如果序列不仅是一个排序好的序列,而且序列的步长大致相同,使用插值查找会更快的找到目标。
插值查找基于如下假设:下标之间的距离比和数据之间的距离比大致相同,即:
(目标下标-最小下标) / (最大下标 - 最小下标) ≈ (目标值 - 最小值) / (最大值 - 最小值)
因此可以算出大致的下标落点:
目标下标 ≈ (目标值 - 最小值) / (最大值 - 最小值) * (最大下标 - 最小下标) + 最小下标
这样就可以计算出大致的下标落点,后续的比较和二分查找一样。

/**
 * 插值查找
 * @param {*} arr 
 * @param {*} target 
 */
function interpolationSearch(arr,target){
    if (arr.length === 0 || target < arr[0] || target > arr[arr.length - 1])    return false;
    var minIndex = 0;//最小下标
    var maxIndex = arr.length - 1;//最大下标
    while (minIndex <= maxIndex){
        num++;
        var mid = (target - arr[minIndex]) / (arr[maxIndex] - arr[minIndex]) * (maxIndex - minIndex) + minIndex;
        if  (arr[mid] === target){
            return true;
        }else if(arr[mid] > target){
            maxIndex = mid - 1;
        }else{
            minIndex = mid + 1;
        }
    }
    return false;

}

测试数据:

var arr = new Array(100000);
for ( var i = 0; i < arr.length; i++){
    arr[i] = i +1;
}
    
// var  result = inOrderSearch(arr,100000);
// var  result = binarySearch(arr,100000);
var  result = interpolationSearch(arr,100000);
console.log(result,num);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值