Stan Blog

學習過程中的一些記錄

[Algorithm] Quick Sort (快速排序)

快速排序(英語:Quicksort),又稱分割區交換排序(partition-exchange sort),簡稱快排

Quick Sort 的定義 (參考維基百科)

快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為較小和較大的2個子序列,然後遞迴地排序兩個子序列

主要步驟

  1. 從數列中挑選一個基準點,接著分別由數列的兩邊開始往中間找

  2. 如果右邊找到一個值比基準點小,左邊找到一個值比基準點大,就將他們互換

  3. 如此將所有數列跑過一輪即可完成排序

用文字描述起來比較抽象 XD,有點類似二元分類的概念,可以參考維基上的動圖比較好懂

維基百科 - 快排動圖

時間複雜度 O(nlogn)

以下實作皆為 in-place 版本 (即不建立新 array,直接操作原 array)

範例程式碼

Ruby 範例

附上 Ruby 的 online sandbox,有興趣可以把 code 貼進去玩玩看

arr = [9, 4, 2, 3, 5, 7, 8, 1, 6]

def quick_sort(array, first, last)
  if first < last
    p_index = partition(array, first, last)
    quick_sort(array, first, p_index-1)
    quick_sort(array, p_index+1, last)
  end
  return array
end

# 從 array 中選出一個 pivot 當作基準,用這個 pivot 將 array 切成兩半,使左半邊數值全都小於 pivot,右半邊數值全都大於等於 pivot
def partition(array, first, last)
  pivot = array[last]
  dividing_index = first

  (first...last).each do |index|
    value = array[index]
    # 如發現小於等於 pivot 的值時,就跟大於 pivot 的值交換位置
    if value <= pivot
      array[index] = array[dividing_index]
      array[dividing_index] = value
      dividing_index += 1
    end
  end

  # 將 pivot 交換至 dividing_index 位置,這樣 dividing_index 左邊的值都會小於等於 pivot,右邊都會大於 pivot
  array[last] = array[dividing_index]
  array[dividing_index] = pivot
  dividing_index
end

pp quick_sort(arr, 0, 8)

結果如下

螢幕快照 2020-11-10 17 50 11

JavaScript 範例

JavaScript 的 online sandbox,有興趣可以把 code 貼進去玩玩看

let arr = [9, 4, 2, 3, 5, 7, 8, 1, 6]

const quickSort = (array, first, last) => {
  if (first < last) {
    let pivotIndex = partition(array, first, last);
    quickSort(array, first, pivotIndex-1);
    quickSort(array, pivotIndex+1, last);
  }

  return array;
};

const partition = (array, first, last) => {
  const pivot = array[last];
  let dividing_index = first;

  for (let i = first; i < last; ++i) {
    if (array[i] <= pivot) {
      swap(array, dividing_index, i);
      dividing_index++;
    }
  }

  swap(array, dividing_index, last);

  return dividing_index;
}

const swap = (list, a, b) => [list[a], list[b]] = [list[b], list[a]];

console.log(quickSort(arr, 0, arr.length - 1));

結果如下

螢幕快照 2020-11-11 13 50 29

Comments

comments powered by Disqus