通过该篇博客的学习,理解了快速排序的几个重要点:
1、如何选取pivot值
一般,都会选择首位值或者末尾值,因为这样取值相对很方便,传入的数组下标容易得到。其次,将所选首位值(假若是首位)先存放一个变量中不动,然后利用填坑原理,让首位值变成“坑”。
2、如何扫描数组
在进行一次Partion(一次快速排序)时,可以有两种方式对数组进行扫描比对。
<1>双向扫描:是以所选的pivot为基准,两个指针从数组的首尾向中间扫描。尾指针遇到比pivot小与或等于的数值,与当前的“坑”进行交换,并产生新的“坑”。然后,首指针遇到比pivot大于或等于的数值,与当前的“坑”再进行交换。最后,将pivot的值赋值给最后一次主动要交换的数组位置。
<2>单向扫描:是两个指针一前一后同时向前开始扫描指针,由于该方法的效率要低于双向扫描的方式,故而在此不做详细的描述。有兴趣的朋友,可以自行查看大师具体博客中的内容讲解和代码实现。
3、关于要排序的长度
由于快速排序可以应用到去解决Top K问题,因此再选择排序的时候,end(后面的具体代码实现中可以看到)的取值要注意。当end小于数组的length时,可以对前end+1个值排序;当end = length-1时,会对整个数组进行排序,但此时会在数组的末尾增加一位,其数值为undefined。当end >= length时,就会陷入死循环。
具体的代码实现,如下:
function quickSort(arr, start, end) {
var i = start,
j = end,
pivot = arr[i];
while (i < j){
while (i < j && arr[j] >= pivot) //找出比pivot小于等于的值
j--;
arr[i] = arr[j];
while (i < j && arr[i] <= pivot) //找出比pivot大于等于的值
i++;
arr[j] = arr[i];
}
arr[i] = pivot;
if(start < end){
quickSort(arr, start, i-1); //左边迭代
quickSort(arr, i+1, end); //右边迭代
}
}
暂时先理解了快速排序算法的一个基本实现,至于BFPRT算法(对快速排序算法的优化)之后在理解清楚之后再做具体的解释。当然,快速排序算法不止一种优化方法,还有其他的优化方法和思想值得去学习和借鉴。再唠叨几句(借此送给不断在变强的你我),在学习的路上,请保持专注,并且对知识保持一种饥渴感,促使自己不断去提升。当某一天突然回眸,你会很庆幸的发现,这个过程是多么的珍贵和难忘。