吐血整理,不知道为什么突然去研究了一下JavaScript的sort函数的底层实现方法。开始我以为sort排序是使用冒泡排序来实现的,但是仔细研究发现并不是,百度之后发现了各种各样的答案,得到的答案是:sort底层是实现依据是快速排序(但好像也不是很准确)
于是我就去复习了一下快排的原理,依稀记得上数据结构课的时候被各种排序算法所折磨,还要研究它的时间复杂度,可怜我数学不好,就愣是没有搞明白。为了彻底解决这一问题,我在bilibili上找到了快速排序的讲解视频,看完之后我豁然开朗。but,问题来了,原理懂了,但是如何实现编程呢,感觉一口老血喷出来。
好吧,我们要坚持,不要轻言放弃。在网上找到了快排的现成的代码开始研究。但是好像看不懂( •̀ ω •́ )y,无语子,怎么办,使用调试工具按照执行顺序理了一下思路,发现好像懂了一点点,但是没有关系。我使用最原始的方法在草稿纸上,理了一下整体的思路,哈哈,豁然开朗。我懂了,是不是很神奇,我来把这种神奇的感觉带给大家。ok上代码
JavaScript版
选取最后一个为基准值,简单粗暴,大的放右边,小的放左边。
const quickSort = (array) => {
const sort = (arr, left = 0, right = arr.length - 1) => {
if (left >= right) {
//如果左边的索引大于等于右边的索引说明整理完毕
return;
}
let i = left;
let j = right;
const baseVal = arr[j]; // 取无序数组最后一个数为基准值
/**
* 前面这些代码就是最基础的,按照快排的思路,取最后一个数为基准值,将left和right指针分别指向数组的两边。
* 将大于基准值的放在右边,小于基准值的放左边!!!
*/
while (i < j) {
/**
*
* 因为取了最后的一个数为基准,所以我们从左边开始移动左边的指针【i】,在保证左右指针不重合的情况下找到比基准值大的数
* 遇到小于基准值的数,就移动指针i++;遇到大于基准值的数,跳出循环,将该数移动到右边
*/
//把所有比基准值小的数放在左边大的数放在右边
while (i < j && arr[i] <= baseVal) {
//找到一个比基准值大的数交换
i++;
}
arr[j] = arr[i]; // 将较大的值放在右边如果没有比基准值大的数就是将自己赋值给自己(i 等于 j)
/**
* 遇到大于基准值的数,就移动指针j--;遇到小于基准值的数,跳出循环,将该数移动到左边
*/
while (j > i && arr[j] >= baseVal) {
//找到一个比基准值小的数交换
j--;
}
arr[i] = arr[j]; // 将较小的值放在左边如果没有找到比基准值小的数就是将自己赋值给自己(i 等于 j)
}
/**
* 左右指针移动完毕,i==j指针重合,跳出循环,此时,arr[j]左边的数都比基准值小,右边的数都比基准值大。
*/
arr[j] = baseVal; // 将基准值放至中央位置完成一次循环(这时候 j 等于 i )
sort(arr, left, j - 1); // 将左边的无序数组重复上面的操作
sort(arr, j + 1, right); // 将右边的无序数组重复上面的操作
};
const newArr = array.concat(); // 为了保证这个函数是纯函数拷贝一次数组
sort(newArr);
return newArr;
};