js实现规范的快排

前言

js写快排并不难 但是网上很多js版本的快排并不规范

错误示例1

function test(nums){
    if(nums.length <= 1) return nums; 
    let left = [],right = [];
    let target = nums[0];
    for(let i=1;i<nums.length;i++){
        if(nums[i]>target) right.push(nums[i])
        if(nums[i]<=target) left.push(nums[i])
    }
    // left.push(target);
    return test(left).concat(target).concat(test(right));
}
let nums = [3,2,2,1,4];
let res = test(nums);

如上所示 上述快排看上去貌似没问题 但是实质上违背了快排的原则 快排的本质是交换 但是上述代码并没有体现出交换,因此并不规范

错误示例2

/**
 * @author vigdxx@gmail.com
 * @param {Array} arr 待排序数组
 */
 function quickSort(arr) {
    /**
     * @description 对数组的一部分进行排序,快排的基准为取待排序部分首项
     * @param {Number} i  待排序部分开始位置
     * @param {Number} j 待排序部分结束位置
     */
    function sort(i,j) {
        // if(i >= j) {return} // 递归出口 
        // let start = i;
        // let end = j;

        if(i>=j) return;
        let start = i;
        let end = j;

        while(i < j) {
            for(;j>i;j--) {
                if(arr[i] > arr[j]) {
                    [arr[j],arr[i]] = [arr[i],arr[j]];
                    break;
                } 
            }
            // 这个地方用 ++i,可以少一次比较
            for(;i<j;i++) {
                if(arr[i] > arr[j]) {
                    [arr[j],arr[i]] = [arr[i],arr[j]];
                    break;
                } 
            }
        }
        // 此时 i == j , arr[i] 左边的小于等于 arr[i],右边的大于arr[i]
        sort(start,i-1);
        sort(i+1,end)
    }
    sort(0,arr.length - 1);
    return arr;
}
let arr = [ 30, 6, 78, 20, 1, 90 ];
console.log(quickSort(arr));

上述代码貌似也没有问题 但是确没有体现出枢纽,快排算法的第一步就是确定枢纽;

规范的快排

/**
 * @author vigdxx@gmail.com
 * @param {Array} arr 待排序数组
 */
 function quickSort(arr) {
    /**
     * @description 对数组的一部分进行排序,快排的基准为取待排序部分首项
     * @param {Number} i  待排序部分开始位置
     * @param {Number} j 待排序部分结束位置
     */
    function sort(i,j) {
        if(i >= j) {return} // 递归出口 
        let start = i;
        let end = j;
        let privot = arr[start];
        while(i < j) {
            while(i<j&&arr[j]>=privot) j--;
            arr[i] = arr[j];
            while(i<j&&arr[i]<=privot) i++;
            arr[j] = arr[i];
        }
        arr[i] = privot;
        sort(start,i-1);
        sort(i+1,end)
    }
    sort(0,arr.length - 1);
    return arr;
}
let arr = [ 30, 6, 78, 20, 1, 90 ];
console.log(quickSort(arr));

上述是笔者用js实现的快排 既体现了枢纽 又体现出了交换的思想;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值