js实现快速排序

js实现快速排序

基本思想

快速排序是对冒泡排序的改进,基本思想是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小,然后再按此方法对两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据的有序。

推导过程

在这里插入图片描述

动画演示

在这里插入图片描述

代码实现

let arr = [7,6,8,1,2,0,4,3,9,5];
function quickSort(arr,left,right){
    let l = left;//左下标
    let r = right;//右下标
    let pivot = arr[Math.floor((l+r)/2)];//中轴值
    let tmp =0;//临时变量,作为交换时使用
    //while循环的目的是让比pivot值小的放到左边,比pivot值大的放到右边
    while(l<r){
        //在pivot的左边一直找,直到找到大于等于pivot的值,才退出
        while(arr[l] < pivot){
            l+=1;
        }
        //在pivot的右边一直找,直到找到小于等于pivot值,才退出
        while(arr[r] > pivot){
            r-=1;
        }
        //如果l >= r说明pivot 左右两边的值,已经按照左边全都是小于等于pivot的值,右边全是大于等于pivot值
        if(l >= r){
            break;
        }
        //交换
        tmp = arr[l];
        arr[l] = arr[r];
        arr[r] = tmp;
        //如果交换完后,发现arr[l]==pivot值相等,r=r-1
        if(arr[l]==pivot){
            r-=1;
        }
        //如果交换完后,发现arr[r]==pivot值相等,l++
        if(arr[r]==pivot){
            l+=1;
        }
        //如果l==r,必须l++,r--否则会出现栈溢出
        if(l==r){
            l+=1;
            r-=1;
        }
        //向左递归
        if(left < r){
            quickSort(arr,left,r);
        }
        //向右递归
        if(right > l){
            quickSort(arr,l,right);
        }
    }
    return arr;
}
console.log(quickSort(arr,0,arr.length-1));//[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

复杂度分析

快速排序在最坏情况下的时间复杂度和冒泡排序一样,是 O(n2),实际上每次比较都需要交换,但是这种情况并不常见。我们可以思考一下如果每次比较都需要交换,那么数列的平均时间复杂度是 O(nlogn),事实上在大多数时候,排序的速度要快于这个平均时间复杂度。这种算法实际上是一种分治法思想,也就是分而治之,把问题分为一个个的小部分来分别解决,再把结果组合起来。

快速排序只是使用数组原本的空间进行排序,所以所占用的空间应该是常量级的,但是由于每次划分之后是递归调用,所以递归调用在运行的过程中会消耗一定的空间,在一般情况下的空间复杂度O(logn),在最差的情况下,若每次只完成了一个元素,那么空间复杂度为 O(n)。所以我们一般认为快速排序的空间复杂度为 O(logn)

快速排序是一个不稳定的算法,在经过排序之后,可能会对相同值的元素的相对位置造成改变。

快速排序基本上被认为是相同数量级的所有排序算法中,平均性能最好的。

算法的时间复杂度和空间复杂度是可以相互转化的。

谷歌浏览器相比于其他的浏览器,运行速度要快。是因为它占用了更多的内存空间,以空间换取了时间。

算法中,例如判断某个年份是否为闰年时,如果想以时间换取空间,算法思路就是:当给定一个年份时,判断该年份是否能被4或者400整除,如果可以,就是闰年。

如果想以空间换时间的话,判断闰年的思路就是:把所有的年份先判断出来,存储在数组中(年份和数组下标对应),如果是闰年,数组值是1,否则是0;当需要判断某年是否为闰年时,直接看对应的数组值是1还是0,不用计算就可以马上知道。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独立寒秋-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值