算法系列——JavaScript快速排序思想實現

原理

快速排序離不開遞歸的思想,你若是不瞭解遞歸,能夠結合我另一篇文章來學習 算法入門之遞歸分而治之思想的實現javascript

網上有有趣的動態圖來表示快速排序,但其實咱們大部分程序員都是腦子不太好使那種,即便看了形象生動的動態圖,仍是想不到具體實現思路。java

排序都有基本的步驟,快排也不例外,一般分爲這麼幾步:程序員

一、選擇基準值;算法

二、須要2個空數組,分別位於基準值的左邊和右邊,小於基準值的push到左邊的數組,大於基準值的push到右邊的數組;segmentfault

三、遞歸重複上面的步驟。數組

具體思路分析

原始數組 [2, 4, 1, 5, 3, 1]
找基準值 base 末尾元素1
拆分 left [1] <- [base] -> [2, 4, 5, 3] right
遞歸 對left和right的數組重複第一步找新的基準值
模擬遞歸1 [1], [1], [2] <- [3] -> [4, 5]
模擬遞歸2 [1], [1], [2], [3], [4] <- [5] -> []
遞歸結束,合併數組 [...[1], ...[1], ...[2], ...[3], ...[4], ...[5]]

這個表格模擬快速排序的具體步驟,遞歸是將一種規律重複執行N次的操做,咱們找到快速排序的規律,而後return 遞歸,當遞歸到數組爲1個元素時,再也不遞歸,由於只剩一個元素的數組不須要再比較了。函數

JavaScript源碼實現快速排序

理論理解起來很容易,但常常是實際寫代碼,無從下手,下面是我根據快排的步驟實現的遞歸快速排序。qSort函數不復雜,他表示執行一次找基準值而且遍歷比較的過程,而你可能不太理解的是函數最後面的return。學習

return [...qSort(left), ...[base], ...qSort(right)]

將這個return拆分開來看。code

一、返回值應該是個數組 。排序

return []

二、合併第一次快速排序的left,base,right數組。接着就交給遞歸去執行左邊和右邊數組的排序。

return [qSort(left), [base], qSort(right)]

三、由於qSort返回的是數組,不是數組元素,因此須要用ES6語法...來散列開。

完整代碼:

function qSort(arr) {
  //聲明並初始化左邊的數組和右邊的數組
  var left = [], right = []
  //使用數組最後一個元素做爲基準值
  var base = arr[arr.length - 1]
  //當數組長度只有1或者爲空時,直接返回數組,不須要排序
  if(arr.length <= 1) return arr
  
  //進行遍歷
  for(var i = 0, len = arr.length; i < len - 1; i++) {
    if(arr[i] <= base) {
    //若是小於基準值,push到左邊的數組
      left.push(arr[i])
    } else {
    //若是大於基準值,push到右邊的數組
      right.push(arr[i])
    }
  }
  //遞歸而且合併數組元素
  return [...qSort(left), ...[base], ...qSort(right)]
}
const arr = [2, 4, 1, 5, 3, 1]
const s = qSort(arr)

console.log(s) // [1, 1, 2, 3, 4, 5]

時間複雜度

快速排序的平均時間複雜度是O(nlogn),最差狀況是O(n²)。

相關文章
相關標籤/搜索