Javascript常用的查找算法一般有两种:线性查找和二分法查找,这两种算法使用环境不同,查询性能也不同,下面我们来看下这两种算法比较。
线性查找
顾名思义,线性查找就是遍历整个要查找的集合,知道找到目标为止。线性查找的优点是原理简单,对集合顺序没有要求,确定是性能不稳定,具体性能取决于目标在查找集合中的位置。举个,当目标元素在集合中靠前的位置时查找耗时较短,如果目标元素在集合中靠后的位置时,查找耗时较长。下面我们来看下代码实现:
function find2(arr,val) {
for(let i=0,len=arr.length;i<len;i++) {
if(arr[i]==val) {
console.log("找到元素,索引为:"+i)
}
}
}
二分法查找
二分法查找的特点是查找效率较高,适合大数据量级,查找耗时与目标在集合中所在位置无关。其主要实现思想是将集合一分为二,将中间数值与目标数值做比较,确定下次查找的大致范围,然后依此类推,知道找到目标元素为止。其局限性在于目标集合必须是有序的,因为只有目标集合有序才能在对中间值与目标值相比较后确定下次查找范围,从而提高查找效率。下面我们看下代码实现:
function find(arr,val,start,end) {
let mIndex = Math.floor((start+end)/2)
let midVal = arr[mIndex]
if(midVal==val) {
console.log("找到元素,索引为:"+mIndex)
} else if(val<midVal) {
find(arr,val,start,mIndex)
} else if(val>midVal) {
find(arr,val,mIndex,end)
}
}
总结
以上两种算法是针对与普通数组的查找,不适用于其它数据结构。我们可以将两种算法的的耗时做个比较:
var findIndex = 2500000;
function main() {
let arr = [...getRandomArray(5000000)]
arr = arr.sort(function(a,b){
return a-b
})
let time = Date.now()
console.log("开始二分法查找...")
find(arr,arr[findIndex],0,arr.length-1)
console.log("用时为:"+(Date.now()-time)+'ms')
let time2 = Date.now()
console.log("开始线性查找...")
find2(arr,arr[findIndex])
console.log("用时为:"+(Date.now()-time2)+'ms')
}
function getRandomArray(num) {
let result = new Set()
for(let i=0;i<num;i++) {
result.add(Math.ceil(Math.random()*num))
}
return result;
}
function find(arr,val,start,end) {
let mIndex = Math.floor((start+end)/2)
let midVal = arr[mIndex]
if(midVal==val) {
console.log("找到元素,索引为:"+mIndex)
} else if(val<midVal) {
find(arr,val,start,mIndex)
} else if(val>midVal) {
find(arr,val,mIndex,end)
}
}
function find2(arr,val) {
for(let i=0,len=arr.length;i<len;i++) {
if(arr[i]==val) {
console.log("找到元素,索引为:"+i)
}
}
}
main()
最后运行结果为:
在目标元素集数据量为50w,目标位置为中心位置情况下,线性查找耗时9ms,二分法查找耗时2ms.