快排和二分查找

334 阅读1分钟

前端中面试排序和查找的可能性比较小,因为 JS 引擎已经把这些常用操作优化得很好了,可能项目中你费劲写的一个排序方法,都不如Array.sort速度快且代码少。因此,掌握快排和二分查找就可以了。

快排和二分查找都基于一种叫做「分治」的算法思想,通过对数据进行分类处理,不断降低数量级,实现O(logN)(对数级别,比O(n)这种线性复杂度更低的一种,快排核心是二分法的O(logN),实际复杂度为O(N*logN))的复杂度。

快速排序

快排大概的流程是:

  1. 随机选择数组中的一个数 A,以这个数为基准
  2. 其他数字跟这个数进行比较,比这个数小的放在其左边,大的放到其右边
  3. 经过一次循环之后,A 左边为小于 A 的,右边为大于 A 的
  4. 这时候将左边和右边的数再递归上面的过程

具体代码如下:

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