原文出自:javascript
http://www.nczonline.net/blog/2012/11/27/computer-science-in-javascript-quicksort/java
https://gist.github.com/paullewis/1981455#file-gistfile1-jsgit
快速排序(Quicksort)是對冒泡排序的一種改進,是一種分而治之算法歸併排序的風格github
核心的思想就是經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據都比另一部分的全部數據都要小,而後再按此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸進行,以此達到整個數據變成有序序列算法
理論上的步驟:數組
原文太羅嗦了,簡單的來講函數
來個實際的demo性能
var items = [4, 2, 6, 5, 3, 9];
具體的流程算法以下:ui
針對這一組數組,如何選擇這個支點呢,有些算法選擇第一項爲支點, 這是否是最好的選擇,性能最差。 通常更好地選擇數組中間的支點,因此考慮5是樞軸值(數組的長度除以2)spa
接下來從左邊拿0位置拿第一個數與支點5對比,若是4<5,那麼指針的位置就偏移到1,而後2<5,一次類推
若是6>5的時候,此時左邊的指針就中止移動
而後從右邊的指針開始移動,也是如此,只是右邊是取的大於的值,好比9>5 ,往前移位,3<5,此時也中止移動,而後交換指針對應的數值
第二步: 指針在先後開始偏移
第三步:若是4<5,繼續移動左邊的指針往下
第四步:若是2<5,往下,6>5中止
第五步:9>5,往前,3<5中止
第六步:交換指針指向的值
第七步:繼續如上的操做,直到支點
第八部:若是指針到了支點,就中止
配合實現交換的swap的代碼
function swap(items, firstIndex, secondIndex){ var temp = items[firstIndex]; items[firstIndex] = items[secondIndex]; items[secondIndex] = temp; }
實現的代碼
function partition(items, left, right) { var pivot = items[Math.floor((right + left) / 2)], i = left, j = right; while (i <= j) { while (items[i] < pivot) { i++; } while (items[j] > pivot) { j--; } if (i <= j) { swap(items, i, j); i++; j--; } } return i; }
這個函數接受三個參數: items
,這是值進行排序的陣列, left
,這是該指數以啓動左指針時,和right
,這是該指數以啓動右指針。 樞軸值是經過將所肯定的left
和right
的值,而後除以2。 由於這個值多是一個浮點數,有必要進行一些舍入。
整個算法是循環只是一個循環。 外環肯定什麼時候全部的數組範圍的項目已經被處理。 左,右指針的兩個內部循環控制運動。當兩個內部循環的完成,則該指針進行比較,以肯定是否交換是必要的。 在交換以後,兩個指針被移動,使外循環繼續,在合適的地方。 該函數返回的左指針的值,由於這是用於肯定從哪裏開始隔間的下一次。 請記住,該分區是發生在地方,而不會產生任何額外的數組。
快速排序算法基本上經過劃分整個陣列的工做原理,而後遞歸地分割陣列的左側和右側的部分,直到整個陣列被排序。
在前面的例子中,數組變[4, 2, 3, 5, 6, 9]
一個分區,並返回索引後爲4(左指針的最後一個席位),開始遞歸左右2個分割陣列
以下面的圖所示
第一步:找到指針遍歷的位置,肯定支點
第二步:從左右指針位置開始,對比4<3,中止
第三步:由於5>3,移動右邊的指針,由於3==3,中止
第四步:交換指針指向的值
第五步:依次如上處理
第六步:由於2<3,移動左邊指針,由於4>3,中止
由於左邊的指針超過了右邊的指針,中止
該過程以後,該陣列變成[3, 2, 4, 5, 6, 9]
和返回的索引是1,繼續這樣,直到全部的陣列左側的排序。 而後相同的處理接着在右側的陣列。 基本對數的快速排序,而後變得很是簡單:
function quickSort(items, left, right) { var index; if (items.length > 1) { index = partition(items, left, right); if (left < index - 1) { quickSort(items, left, index - 1); } if (index < right) { quickSort(items, index, right); } } return items; } // first call var result = quickSort(items, 0, items.length - 1);
快速排序一般被認爲是高效,快速等特色是使用V8引擎的實現Array.prototype.sort()
上有超過23個項目的數組。 對於少於23個項目,V8採用插入排序法[2]。
歸併排序是快速排序的競爭對手,由於它也是高效,快捷,但有被穩定的好處。 這就是爲何Mozilla和Safari中使用它本身的執行Array.prototype.sort()