活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
前言:
算法在程序工作中的重要意义就不再赘述了,想必您已经非常清楚了,话不多说,直接开干。
查找和排序是工作中的基本问题,在很多需求中都存在,因此就来聊聊查找算法和排序算法。由于篇幅限制此篇就先聊聊查找算法。
查找算法顾名思义,就是找到自己需要的东西。那么,从什么中找呢,可以是一堆数字,例如:[90,34,123543,6543,3235,423];也可以是一堆对象,例如:[{name:“mike”},{name:“bob”}],也可以是字符串,例如:[“hello”,“world”]。那么,又该怎么找呢,接下来就说一说,查找算法的具体方法。
顺序查找
顺序查找思路
顾名思义,顺序查找就是按照顺序查找,这个顺序是指数据在数组中的自然顺序,不是数据本身具有意义的顺序。就是从第一个开始查找直到找到或者直到最后一个。如果找到了就不必再继续找了返回什么由自己决定。
顺序查找过程
第一次:从第一个数据开始比对,与目标值不一致
第二次:与第二个数据比对,与目标值不一致
第三次:与第三个数据比对,与目标值不一致
第四次:与第四个数据比对,与目标值不一致
第五次:与第五个数据比对,与目标值一致,退出查找
代码
纸上得来终觉浅,觉知此事要躬行。接下来就用一个例题,具体感受一下。
需求:在一个有n个数字元素的数组nums中查找数字m,如果找到了返回其下标否则返回-1。
function search(nums, m){
for(let i = 0, len = nums.length; i < len; i++){
if(nums[i] === m){
return i;
}
}
return -1;
}
这道题比较简单,就是从第一个元素开始,每个元素都和m代表的值进行比对,如果值相等就是返回其下标,否则等循环结束说明没有找到就返回-1。不过在工作中只知道顺序查找还是不够,主要是因为在遇到数据较多的情况下,顺序查找就很慢,需要半天才找到,严重影响性能,如果没有交互动画提示时,甚至还会以为是bug。因此还需要学习其他查找方法。
二分查找
二分查找思路
二分查找,有时也叫折半查找。顾名思义,就是把一堆数据以中间的那个数为中心从中间分开,如果要查找的数比中间那个数大,就在中间数的右半边中查找,如果比要查找的数小就在左半边中找。右半边/左半边也和上一步一样,以中间数为中心分开,再次与要找的数比较,一直这样找下去或者直到数组的头和尾重合。
二分查找过程
第一次:middle=2,指向值为3的数据,与target不等
第二次:middle=1,执行值为2的数据,与target相等,结束查找
示例
好了,光说不练假把式,先弄个题练练先。
需求:在一个有n个数字元素的数组nums中查找元素m,如果找到返回其下标否则返回-1。
function binSearch(nums,m){
let end = nums.length - 1;
let start = 0;
while(start <= end){
let mid = Math.floor((end + start) / 2);
if(arr[mid] < m){
start = mid + 1;
} else if(arr[mid] > m){
end = mid - 1;
} else {
return mid;
}
}
return -1;
}
二分查找需要找一个中间数,怎么找呢,一般就是取数组中的中间下标所指的元素。一般是把数组的长度除以2,取商的整数,这是为了避免除不尽导致存在小数不好判断的情况。毕竟javascript语言的商有小数。把中间数取好之后就开始比较,就和刚才说的一样,比中位数大向尾部找,小了向头部找,直到找到或者没找到,以上就是二分查找法。
二分排序比顺序查找法要快,毕竟一半一半的找比从头找到尾要快。
不过需要数组是有序的即排好序的,不管是从小到大(升序)还是从大到小(降序)都可以
如果是从大到小,只需要将
if(arr[mid] < m){
start = mid + 1;
} else if(arr[mid] > m){
end = mid - 1;
} else {
return mid;
}
换成
if(arr[mid] < m){
end = mid - 1;
} else if(arr[mid] > m){
start = mid - 1;
} else {
return mid;
}
即可。
查找最小值和最大值
将数组的第一个元素赋值给一个变量,作为最小值,将其与下一个元素相比,如果比变量值小将该值赋值给变量。
function getMin(arr){
let min = arr[0];
for(let i = 0; i < arr.length; i++){
if(arr[i] < min){
min = arr[i];
}
}
return min;
}
function getMax(arr){
let max = arr[0];
for(let i = 0; i < arr.length; i++){
if(arr[i] > max){
max = arr[i]
}
}
return max;
}
自组织数据
数据在程序运行过程中自动组织。“80-20原则”:对一个数据集的80%查找操作都是对其20%的数据进行的操作。
将查找的元素向前移动一个位置,当数据被查询的足够频繁被查找的数据最终会移动到数组首部。
function search(arr, data){
for(let i = 0; i < arr.length; i++){
if(arr[i] === data){
if(i > 0){
let temp = arr[i - 1];
arr[i - 1] = arr[i];
arr[i] = temp;
}
return true;
}
}
return false;
}