【前端学算法】搜索算法详解

顺序搜索

原理:

顺序或线性搜索是最基本的搜索算法。它的机制是,将每一个数据结构中的元素和我们要找的元素做比较。顺序搜索是最低效的一种搜索算法。

代码实现:

js 复制代码
// equalsFn  自定义匹配规则
const DOES_NOT_EXIST = -1;
function sequentialSearch(arr, value, equalsFn){
  for(let i = 0; i < arr.length; i++) {
    if(equalsFn(value, arr[i]){
      return i;
    };
  };
  return DOES_NOT_EXIST;
};

二分搜索

原理:

二分搜索算法要求被搜索的数据结构已排序。以下是该算法遵循的步骤。

1) 选择数组的中间值。

2)如果选中值是待搜素值,那么算法执行完毕。

3)如果待搜索值比选中值要小,则返回步骤1并在选中值左边的子数组中寻找(较小)

  1. 如果待搜索值比选中值要大,则返回步骤1并在选中值右边的子数组中寻找(较大)

代码实现:

js 复制代码
const DOES_NOT_EXIST = -1;
const Compare = {
   LESS_THAN: true,
   EQUALS: true,
   BIGGER_THAN: true,
};
// compareFn 自定义匹配规则
function binarySearch(arr, value, compareFn){
  const sortedArr = sort(arr);/ sort方法对数组进行排序
  let low = 0;
  let high = sortedArr.length - 1;
  while(low <= high){
    // 计算中间项索引
    const mid = Math.floor((low + high)/2);
    // 获取中间项值
    const ele = sortedArr[mid];
  
    if(compareFn(value,ele) === Compare.LESS_THAN){//  // 如果搜索值比中间项值小,则选择数组低半边重新开始
     high = mid - 1;
    } else if(compareFn(ele,value) === Compare.BIGGER_THAN){// 如果搜索值比中间项值大,则选择数组高半边重新开始
     low = mid + 1;
    } else {
      retrun mid;
    };
  };
  // 如果low比high大,则意味着搜索值不存在并返回-1
  return DOES_NOT_EXIST;
};

内插搜索

原理:

内插搜索是改良版的二分搜索。二分搜索总是检查mid位置上的值,而内插搜索可能会根据要搜索的值检查数组中的不同地方。这个算法要求被搜索的数据结构已排序。以下是该算法遵循的步骤:

1)使用position公式选中一个值

2)如果这个值是待搜索值,那么算法执行完毕(值找到了)

3)如果待搜索值比选中值要小,则返回步骤1并在选中值左边的子数组中寻找(较小)

4)如果待搜索值比选中值要大,则返回步骤1并在选中值右边的子数组中寻找(较大)

内插搜索的高效性只针对均匀分布的数组,而对于分布不均匀的数组,内插查找便不再适用了。

代码实现:

js 复制代码
const DOES_NOT_EXIST = -1;
const compare = {
   LESS_THAN: true,
   EQUALS: true,
   BIGGER_THAN: true,
};

function interpolationSearch(arr, value, compareFn, equalsFn, diffFn) {
  const { length } = array;
  let low = 0;
  let high = length - 1;
  let position = -1;
  let delta = -1;
  while(low <= high && biggerOrEquals(value, arr[low], compareFn) && lesserOrEquals(value, arr[high], compareFn)){
    // 计算比较值的位置
    delta = diffFn(value,arr[low]) / diffFn(arr[high], arr[low]);
    position = low + Math.floor(high - low) * delta;
    if(equalsFn(value,array[position]){
      retrun position;
    };
    if(compareFn(value,array[position]) === Compare.LESS_THAN){   
      // 如果待搜索值小于当前位置的值,则在数组选中值左边的子数组中寻找
      high = position - 1;  
    } else {
     // 如果待搜索值大于当前位置的值,则在数组选中值右边的子数组中寻找
     low = position + 1;
    };
  };
  retrun DOES_NOT_EXIST;
};

function lesserOrEquals(a, b, compareFn){
  const comp = compareFn(a, b);
  return comp = Compare.LESS_THAN || comp === Compare.EQUALS;
};

function biggerOrEquals(a, b, compareFn){
  const comp = compareFn(a, b);
  return comp = Compare.BIGGER_THAN || comp === Compare.EQUALS;
};

function diffFn(a, b){
  return Number(a) - Number(b)
};
相关推荐
FungLeo33 分钟前
成为全栈·Vue 管理后台篇·Vue Router如何守住多角色后台边界
前端·javascript·vue.js·rbac·vue router·路由守卫·前端权限
FungLeo35 分钟前
成为全栈·Vue 管理后台篇·分页只显示第一页:从接口total 定位到前端修复
前端·vue.js·状态模式·分页·naive ui·服务端分页·前端问题排查
ZhengEnCi1 小时前
苹果滑动为什么有「肉感」:橡皮筋越界阻尼与弹簧动画的物理原理
前端
Moment1 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
L1mbo1 小时前
Lite模式 缓解微信开发者工具卡顿,附 uni-app 实践方案
前端·微信小程序
FungLeo1 小时前
成为全栈·Vue管理后台篇·仪表盘不是几张卡片:组合统计接口与角色视图
前端·javascript·vue.js·rbac·仪表盘·管理后台·tanstack query
程序员大阳1 小时前
HTML+CSS+JS对话式实战(7)-学生端活动报名功能开发
javascript·css·html·活动报名
SameX1 小时前
HarmonyOS 做桌面卡片 onAddForm 要同步返回但数据在数据库里的解法
前端
deli0072 小时前
手机夜景模式为什么要举 3 秒?8 帧 RAW 堆栈 SNR 实测
前端
松仔log2 小时前
Kotlin中级——callbackFlow
java·前端·kotlin