实现原理

快速排序是一种分治算法,排序方式是当两个子数组都有序的时候整个数组也就有序了。归并排序中,一个数组被一分为二,快速排序中 partition 的位置取决于数组的内容。

切分位置

切分位置要满足三个条件:

  1. 对于某个j,a[j] 已经确定
  2. a[lo] 到 a[j - 1] 中的元素都不大于 a[j]
  3. a[j+1] 到 a[hi] 中的元素都不小于 a[j]

切分算法

随意的取 a[lo] 作为切分元素,向右扫描知道找到一个大于等于它的元素 a[i],再从 a[hi] 开始找知道找到一个小于等于它的元素。如果 i < j 则交换两个元素的内容继续扫描,知道 i >= j 位置。交换 a[lo] 和 a[j] 的内容。
这样就能保证 a[j] 的左边都是小于它的元素,a[j] 的右边都是大于它的元素。

代码实现

  1. func partition(a []int, lo, hi int) int {
  2. i, j := lo + 1, hi
  3. v := a[lo]
  4. for {
  5. for a[i] < v {
  6. i++
  7. if i == hi {
  8. break
  9. }
  10. }
  11. for v < a[j] {
  12. j--
  13. if j == lo {
  14. break
  15. }
  16. }
  17. if i >= j {
  18. break
  19. }
  20. exch(a, i, j)
  21. }
  22. // 交换两个元素,确保切分位置的正确
  23. exch(a, lo, j)
  24. return j
  25. }
  26. func sort(a []int, lo, hi int) {
  27. if hi <= lo {
  28. return
  29. }
  30. j := partition(a, lo, hi)
  31. sort(a, lo, j - 1)
  32. sort(a, j + 1, hi)
  33. }