[路飞] 快速排序

115 阅读2分钟

作用

使数组有序

原理

快排通过递归的方式,来完成对数组的排序,在每一轮中:

  • 选取一个基准值(pivot)
  • 将所有小于它的元素放到左边,将所有大于它的元素放到右边
  • 对于左部分和右部分分别递归

分析

通过上述步骤,我们可以发现,快排实际上会讲数组不断地去划分成更小的区间,由此抛出一个问题,如果数组天然有序,那么是不是我们快排的复杂度实际上和冒泡一样?

为了解决这个问题,我们需要采取一定的优化,为此我们需要用插入排序为快排做优化,另外对于一个快排的区间我们设置为最小 16

优化

我们对于一个数组,首先用快排将它分区,最小分到 16 个为一组,那么组和组之间是相对有序的,每个组的组内元素也是相对有序的

对于每一组元素,我们用插入排序来使它有序,由此降低了快排的复杂度

对于快排,我们用单边快排的方法(对右半部分做递归,左边只做迭代),降低空间复杂度

代码

function quick_sort_V3(arr, l, r) {
        quickSort(arr, l, r)
        final_insert_sort(arr, l, r)
      }

      const THRESHOLD = 16

      const getMid = (a, b, c) => {
        if (a > b) return getMid(b, a, c)
        if (a > c) return getMid(c, b, a)
        if (b > c) return getMid(a, c, b)

        return a
      }

      function quickSort(arr, l, r) {
        while (r - l > THRESHOLD) {
          let x = l,
            y = r,
            base = getMid(arr[l], arr[Math.floor((l + r) / 2)], arr[r]) // make sure it's not the min or max
          do {
            while (arr[x] < base) x++
            while (arr[y] > base) y--
            if (x <= y) {
              // swap
              ;[arr[x], arr[y]] = [arr[y], arr[x]]
              x++
              y--
            }
          } while (x <= y)

          // quick sort on right side
          quickSort(arr, x, r)
          r = y
        }
      }

      // insert sort to handle < 16 scenario
      function final_insert_sort(arr, l, r) {
        let ind = l

        // get index of the min value item
        for (let i = l + 1; i <= r; i++) {
          if (arr[i] < arr[ind]) ind = i
        }

        // swap along until the min value get to l
        while (ind > l) {
          ;[arr[ind], arr[ind - 1]] = [arr[ind - 1], arr[ind]]
          ind--
        }

        // insert sort
        // due to the leftmost is already an sorted one, we start from the 2th index
        for (let i = l + 2; i <= r; i++) {
          let j = i
          while (arr[j] < arr[j - 1]) {
            ;[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]]
            j--
          }
        }
      }