Chapter 34: Quicksort

前言

Quicksort也是comparison-based sorting algorithm跟Merge sort很像,但有一個很重要特性Quicksort利用pivot來分割資料集

[ elements < pivot | pivot | elements > pivot ]

大綱

  • Example

  • Partitioning strategies

    • Lomuto’s partitioning

    • Hoare’s partitioning

  • Effects of a bad pivot choice

    • Median of three

    • Dutch national flag partitioning

Example

  • 每次都選擇中間當pivot

public func quicksortNaive<T: Comparable>(_ a: [T]) -> [T] {
  guard a.count > 1 else {
    return a
  }
  let pivot = a[a.count / 2]
  let less = a.filter { $0 < pivot }
  let equal = a.filter { $0 == pivot }
  let greater = a.filter { $0 > pivot }
  return quicksortNaive(less) + equal + quicksortNaive(greater)
}
  • Calling filter three times on the same array is not efficient.

  • Creating a new array for every partition isn’t space efficient. Could you possibly sort in place?

  • Is picking the middle element the best pivot strategy? What pivot strategy should you adopt?

Lomuto’s partitioning

  • Always chooses the last element as the pivot

Hoare’s partitioning

  • Always chooses the First element as the pivot

Median’s partitioning

  • 非最前,非最後,非中間

Dutch national flag partitioning

  • 比前幾個partitioning多處理相同的元素,相同的元素會放在一起

Last updated