快速排序
快速排序也是最常用的排序算法,和归并算法一样,快速排序也采用分治的方法,将原始数组分为较小的数组。(但是并没有像归并排序那样将它们分开)
思路:
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 }