一、二分从查找
最简单的情况:有序数组中不存在重复元素,查找特定元素:
const biaryFind = (sortedArr, target) => {
if (sortedArr.length === 0) return -1
let low = 0
let high = sortedArr.length - 1
while (low <= high) {
const mid = Math.floor((low + high) / 2)
//可写成:low+(high-low)/2。防止数据溢出
//进一步优化 low+((high-low)>>1)。相比除法运算来说,计算机处理位运算要快得多
if (target === sortedArr[mid]) {
return mid
} else if (target < sortedArr[mid]) {
high = mid - 1
} else {
low = mid + 1
}
}
return -1
}
时间复杂度: O(logn)
适用场景:
- 数组,能按照下标随机访问元素
- 数据排好序
- 数据量不能太大,因为需要连续存储空间
二分查找的相关问题:
- 查找第一个值等于给定值的元素
- 查找最后一个值等于给定值的元素
- 查找第一个大于等于给定值的元素
- 查找最后一个小于等于给定值的元素
拓展
对有序链表的查找:跳表,查找时间复杂度O(logn)
二、散列表(Hash Table)
散列表也叫哈希表,使用数组支持按照下标随机访问数据的特性
散列函数计算key,得到散列值,作为下标。
装载因子=填入表中的元素个数/散列表的长度
解决散列冲突:
- 开放寻址法
有线性探测法、二次探测、双重散列(用多个散列函数)
注意点:删除不能直接将元素置空,要做标记,否则影响正常的查找
缺点: 随着插入数据,空闲位置越来越少,冲突概率也变大,查找效率就会降低。适合数据量比较小、装载因子小 - 链表法
每个槽位存一个链表。比较适合存储大对象、大数据量的散列表
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。