快速排序
快速排序也是最常用的排序算法,和歸並算法一樣,快速排序也采用分治的方法,將原始數組分為較小的數組。(但是並沒有像歸並排序那樣將它們分開)
思路:
1.從數組中選擇中間一項作為主元;
2.創建兩個指針,左邊一個指向數組的第一項,右邊指向數組最后一項。移動左指針直到我們找到一個比主元大的元素,接着,移動右指針直到找到一個比主元小的元素。然后交換它們,重復這個過程,直到左指針超過了右指針。這個過程是的比主元小的值都排在了主元之前,而比主元大的值都排在了主元之后,這一步叫划分操作。
3.接着,算法對划分的小數組(較主元小的值組成的子數組,以及較主元大的值組成的子數組)重復之前的兩個步驟,直至數組以完全排序。
注意:划分的依據是根據指定的主元來進行的。選擇主元有好幾種方式,最簡單的是選擇第一項。然而研究表明對於幾乎已排序的數組來說,這不是一個好的選擇,它會導致該算法最差的表現,所以另一種方式是隨機選擇一個數組項或者是選擇中間項。
function quickSort(array){ quick(array, 0, array.length-1); } function quick(array, left, right){ var index; if(array.length > 1){ // 返回每次划分后的左指針的位置 index = partition(array, left, right); if(left < index - 1){ quick(array, left, index - 1) } if(index < right){ quick(array, index, right) } } } // 划分過程 function partition(array, left, right){ // 選擇數組中間項作為主元 // 定義左右兩個指針 var pivot = array[Math.floor(right + left) / 2], i = left, j = right; // 當左邊指針超過右邊指針時結束循環 while(i <= j){ // 移動左指針找到一個大於等於主元的項,然后停止移動左指針 while(array[i] < pivot){ // 若沒有找到就移動左指針 i++ } // 移動右指針找到一個小於等於主元的項,然后停止移動右指針 while(array[j] > pivot){ // 若沒有找到就移動右指針 j-- } // 左右指針停止后,判斷兩個指針的位置, if(i <= j){ // 若左指針沒有超過右指針,交換兩項的值,並移動兩個指針 swap(array, i, j); i++; j--; } } // 返回左指針用來創建子數組 // 當一次循環結束后,比主元小的項全部在主元的左側 return i }