如果你查找的数据是有序的,二分查找比顺序查找算法更高效。
自然语言描述
要理解二分查找算法的原理,可以想象一下玩猜数字游戏的时候,这个数字在 1-100 之间,而要猜的数字由你的朋友决定。游戏规则是你每猜一个数字,你的朋友将会做出一下三种回应中的一种:
- 猜对了
- 大了
- 小了
根据以上规则,最快猜中的方法是 每一次猜中间的数值。
这个策略就是二分查找算法。这个算法只对有序的数据集有效。
- 将数组的第一个位置设置为下边界
- 将数组的最后一个元素所在位置设置为上边界
- 若下边界等于或小于上边界
- 将中点设置为 【(上边界 + 下边界)除以 2】 的值,向下取整
- 如果中点元素小于查询值,则下边界设置为中点元素所在下标加 1
- 如果中点元素大于查询值,则上边界设置为中点元素所在下标减 1
- 否则中点元素就是要查询的值,直接返回中点元素的下标
二分查找算法实现
查找成功返回下标,失败返回 -1
function binSearch(arr, data) {let upper = arr.length - 1let lower = 0while (lower <= upper) {let mid = Math.floor((upper + lower) / 2)if (arr[mid] < data) {lower = mid + 1} else if (arr[mid] > data) {upper = mid - 1} else {return mid}}return -1}
计算重复次数
当 binSearch 函数找到某个值时,如果在数据集中还有其他相同的值出现,那么该函数会定位在类似值的附近。也就是说,其他相同的值,只会出现在已找到值的左边或右边。
我们可以通过两个循环来实现,一个向左循环遍历,查找左边的,另一个向右循环遍历,查找右边的
function count(arr, data) {let count = 0let position = binSearch(arr, data)if (position === -1) return countcount++for (let i = position + 1; i > 0; i--) {if (arr[i] === data) {count++} else {break}}for (let i = position + 1; i < arr.length; i++) {if (arr[i] === data) {count++} else {break}}}
