【JS小记】归并排序 + 快排

归并排序

主要思想

参考该篇资料进行理解,通俗易懂。简而言之,归并排序的步骤就是先划分,再合并,所以只需要两个函数。此外,划分数组只做划分操作,合并数组的时候再进行排序。

实现代码

/**
* @param {number[]} nums
* @return {number[]} 
*/
var sort= function(nums) {    
    //合并的部分就是将两个有序数组合并,跟力扣“合并两个有序链表”处理相似
    //该函数是包括排序部分的
    function heBing(front, end)
    {
        let temp = [];
        while(front.length && end.length)
        {
            if(front[0] > end[0])
            {
                temp.push(end.shift());                
            }
            else
            {
                temp.push(front.shift());                
            }
        }
        //数组不等长的时候,某个为空时,另一个的值还没全部压入
        return [...temp, ...front, ...end];
    }
    //只做划分工作
    function recur(nums)
    {
        if(nums.length < 2)
            return nums;
        //splice参数是整数,所以偶数奇数都可以这么写
        let left = nums.splice(0, nums.length / 2);		        
        return heBing(recur(left), recur(nums));
    }
    return recur(nums);    
};

基本分析

空间复杂度:在合并函数中可以看到,因为需要辅助数组temp来存储子数组,所以空间复杂度为O(n)。个人理解这个n是原数组的n个数组元素,所以需要O(n)。

时间复杂度:O(nlogn)

快速排序

主要思想

每次取数组第一个元素作为参照值,先比较right所指元素与参照值的关系,注意判断left与right的大小关系,避免数组越界访问和不合理的排序;再比较left所指元素与参照值的关系,注意的点相同;最后进行分组即递归调用快排函数,注意输入的边界值。

实现代码

/**
* @param {number[]} nums
* @param {number} left
* @param {number} right
* @return {number[]} 
*/
function quickSort(nums, left, right)
    {
        //终止条件
        if(left >= right)
            return;
        let i = left, j = right;
        let temp = nums[left];                 //要有参照值
        while(left < right)                    //i == j 时,不用再排序
        {
            //比较右边与参照值nums[j]关系
            while(nums[right] > temp && left < right) //个人:left < right是避免数组访问越界
            {
                right--;
            }
            if(left >= right)
            {
                break;
            }
            //此时:nums[right] <= temp                 
            nums[left] = nums[right];
            nums[right] = temp;
            //比较左边与参照值nums[j]关系
            left++;
            while(nums[left] <= temp && left < right)
            {
                left++;
            }
             if(left >= right)
            {
                break;
            }
            //此时:nums[left] > temp,保证“与参照值相等的元素排在其左边”                    
            nums[right] = nums[left];
            nums[left] = temp;
        }
        //当前情况是,left左边是比nums[left]小的,left右边是比nums[left]大的
        //i j 分别是此轮排序最左和最右的边界
        quickSort(nums, i, left - 1);
        quickSort(nums, left + 1, j);
    }    
    quickSort(nums, 0, nums.length - 1);  
    return nums;

基本分析

空间复杂度:虽然不需要额外数组空间存储排序元素,但采用递归就不可避免的消耗内存,一般情况是O(logn)。

时间复杂度:一般情况是O(nlogn),实际排序速度快于O(nlogn)。而最坏情况下与冒泡排序一样需要o(n^2)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值