一图解析JavaScript快速排序原理,看了就不会忘~~

时隔一年(当时是2020.05.02),再看当初写的快排,只能说能排序,但是性能比较差:

1,选取比较元素的时候,没必要浪费两次数学计算去取中间值!也就是这个是没必要的:

const middleIndex = Math.floor(arr.length/2); 

因为本身就是待排数组,取任何一个元素做中间值都一样,因为每一个元素都可能出现在数组的任意位置,完全没不要去取中间元素。

2,用到了数组的高级用法splice去取中间元素,还去操作删除数组,这个删除元素本身就会涉及到底层数据搬移。会降低性能,完全可以优化掉。

const middleValue  = arr.splice(middleIndex,1)[0]; // 把计划做中间数据的元素拿出来

3,空间复杂度高,不是原地排序。

每次拆分都的数组都涉及临时数组leftArr和rightArr。

今天(2021.08.22)将上述3个点优化掉前两个,第三个优化实现有点复杂,往后再尝试。

function quickSort(arr){
    if(arr.length <=1){
        return arr;
    }
    const middleIndex = 0;//  Math.floor(arr.length/2);
    const leftArr = [], rightArr = [], middle = [arr[middleIndex]];
    for(let i=0; i< arr.length; i++){
        if(i !== middleIndex ) {
            if(arr[i] < middle[0]){
                leftArr.push(arr[i])
            }else{
                rightArr.push(arr[i])
            }
        }
        
    }
    return quickSort(leftArr).concat(middle,quickSort(rightArr) )
}

以下是202.05.02的原文,对理解快速排序也还是有帮助。

今天有个朋友问快速排序的原理,用processon给他画了一个图,也顺手贴上来,给需要的朋友使用。

快排的核心原理是:

1,选数组中的中间数据为比较的基数 (其实选哪个都可以,选第一个或者最后一个都行)

2,从头开始遍历数组,跟选出来的中间数进行比较,比中间数小的放左边数组,大的放右边数组

3,此时得到leftArr数组、中间元素、右边数组

4,分别对左边数组执行步骤1~3,直到拆不出数组位置。

5,最后会把拆出来的元素都连起来。

直接上一个流程图,希望一图能胜千言哈:

直接撸代码(Javascript):

var originalArr = [12,23,16,14,12,21,7];

function quickSort(arr) {
    // 只有一个元素的时候就不用排了,直接返回,需要一直拆解到只有一个元素
    if(arr.length<=1){
        return arr;
    }
    // 拿到中间元素
    const middleIndex = Math.floor(arr.length/2); 
    const middleValue  = arr.splice(middleIndex,1)[0]; // 把计划做中间数据的元素拿出来
    let left = [];
    let right = [];
    // 跟别跟中间元素进行大小比较
    for(let i=0;i<arr.length;i++){
        if(arr[i]<=middleValue){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    // 这一步是关键,需要递归的处理
    return quickSort(left).concat(middleValue,quickSort(right));
}

let newArr = quickSort( [...originalArr] );
console.log(`quickSort end, newArr = ${JSON.stringify(newArr)}`);

// 结果: quickSort end, newArr = [7,12,12,14,16,21,23]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值