介绍快速排序:快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
"快速排序"的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,选择一个元素作为"基准"(pivot)。
(2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
(3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
- 方法一
核心:选择"基准"(pivot),并将其与原数组分离,再定义两个空数组,用来存放一左一右的两个子集。
<script>
<!-- 这个是使用合并数组的方式,而不是使用单纯的原地交换来实现最终的目的!-->
function quickSort(arr) {
//检查数组的元素个数,如果小于等于1,就返回。
if (arr.length<=1){
return arr;
}
//找到中间项,在原有的数组中将其移除
let middleIndex=Math.floor(arr.length/2);
let middleValue=arr.splice(middleIndex,1)[0];
// 新建两个左右数组
let leftArr=[];
let rightArr=[];
for (let i=0;i<arr.length;i++){
let item=arr[i];
//比中间值小的值,放到左数组中。大的值放到右数组中
item<middleValue?leftArr.push(item):rightArr.push(item);
}
//递归调用并且将排好的数组进行一个拼接,就是最终的结果
//concat也不适合大量数据的排序,会消耗大量内存
return quickSort(leftArr).concat(middleValue,quickSort(rightArr));
}
let testArr=[1,3,5,2,12,33,44,32,11];
console.log(quickSort(testArr));
</script>
- 分治策略
使用分治策略,通过原地交换而不是创建合并新的数组来实现该方法。
<script>
//定义一个交换函数,使用数组解构的方式交换。
function swap(A,i,j) {
[A[i],A[j]] = [A[j],A[i]];
}
//定义分区函数,返回中心点的位置
function partition(A,lo,hi){
const pivot = A[hi-1];
let i=lo,j=hi-1;
while (i !== j){
A[i] <= pivot?i++:swap(A,i,--j);
}
swap(A,j,hi-1);
//返回中心点的位置
return j;
}
//利用上面两个函数,进行快排的实现
function qsort(A,lo=0,hi=A.length){
if (hi-lo <= 1) return;
const p=partition(A,lo,hi);
//两个分区都进行排序
qsort(A,lo,p);
qsort(A,p+1,hi);
}
//测试结果
const A=[12,32,44,2,456,22,10];
qsort(A);
console.log(A);
</script>
参考链接附上(内置详细动画以及原理介绍,非常详细,推荐学习)
1:https://juejin.cn/post/6844903782019514381#heading-21
2:js讲解常见常用的数据结构:https://www.bilibili.com/video/BV19E411M78q?p=39&spm_id_from=pageDriver