前端中面试排序和查找的可能性比较小,因为 JS 引擎已经把这些常用操作优化得很好了,可能项目中你费劲写的一个排序方法,都不如Array.sort速度快且代码少。因此,掌握快排和二分查找就可以了。
快排和二分查找都基于一种叫做「分治」的算法思想,通过对数据进行分类处理,不断降低数量级,实现O(logN)(对数级别,比O(n)这种线性复杂度更低的一种,快排核心是二分法的O(logN),实际复杂度为O(N*logN))的复杂度。
快速排序
快排大概的流程是:
- 随机选择数组中的一个数 A,以这个数为基准
- 其他数字跟这个数进行比较,比这个数小的放在其左边,大的放到其右边
- 经过一次循环之后,A 左边为小于 A 的,右边为大于 A 的
- 这时候将左边和右边的数再递归上面的过程
具体代码如下:
const quickSort = (arr) => {
quick(arr, 0 , arr.length - 1)
}
const quick = (arr, left, right) => {
let index
if(left < right) {
// 划分数组
index = partition(arr, left, right)
if(left < index - 1) {
quick(arr, left, index - 1)
}
if(index < right) {
quick(arr, index, right)
}
}
}
// 一次快排
const partition = (arr, left, right) => {
// 取中间项为基准
var datum = arr[Math.floor(Math.random() * (right - left + 1)) + left],
i = left,
j = right
// 开始调整
while(i <= j) {
// 左指针右移
while(arr[i] < datum) {
i++
}
// 右指针左移
while(arr[j] > datum) {
j--
}
// 交换
if(i <= j) {
swap(arr, i, j)
i += 1
j -= 1
}
}
return i
}
// 交换
const swap = (arr, i , j) => {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
// 测试
let arr = [1, 3, 2, 5, 4]
quickSort(arr)
console.log(arr) // [1, 2, 3, 4, 5]
// 第 2 个最大值
console.log(arr[arr.length - 2]) // 4