JS算法3 -- 排序 --归并排序、快速排序

归并排序

1.左右两边先排序;
2.再借助辅助数组,指针在左右两个数组中移动,两指针作比较,小的就往辅助数组中填;
3.整体在辅助数组中有序后,拷贝回原数组。

//归并排序 时间复杂度O(n*logn)
var list = [5,2,6,1,22,77,4,12];
console.log('未排序',list);
function merge(arr,l,mid,r){
    var help = [];
    var i = 0;
    var p1 = l;
    var p2 = mid + 1;
    while(p1 <= mid && p2 <= r){
        help[i++] = arr[p1] < arr[p2] ? arr[p1++]:arr[p2++];
    } 
    while(p1 <= mid){
        help[i++] = arr[p1++];
    }
    while(p2 <= r){
        help[i++] = arr[p2++];
    }
    for(i=0; i<help.length; i++){
        arr[l+i] = help[i];
    }
}
function sortProcess(arr,l,r){
    if(l == r){
        return;
    }
    var mid = parseInt((l+r)/2);
    sortProcess(arr,l,mid);
    sortProcess(arr,mid+1,r);
    merge(arr,l,mid,r);
}
function mergeSort(arr){
    if(arr == null || arr.length<2){
        return;
    }
    sortProcess(arr,0,arr.length-1);
}

mergeSort(list);
console.log('归并排序',list);

调试结果如下:
在这里插入图片描述
报错总结:在没有把mid取整时,出现了无限循环的情况
在这里插入图片描述

  • 解决:加入var mid = parseInt((l+r)/2);
    若没有控制好判断条件,在递归中也会很容易出现无限循环的情况
递归算法:

系统中一个函数调子过程之前,会将函数、参数…都压入栈中,子过程返回之后,重新调用栈中函数,彻底还原。

( 自己调用自己 )

//递归找最大值
var nums = [4,3,2,1];
var len = nums.length;
function getMax(arr,l,r){    
    if(l==r){    
        return arr[l];
    }
    var mid = parseInt((l+r)/2);
    var maxLeft = getMax(arr,l,mid);
    var maxRight = getMax(arr,mid+1,r);
    return Math.max(maxLeft,maxRight);
}
console.log(getMax(nums,0,len-1));

调试结果如下:
在这里插入图片描述


快速排序

1.每一趟排序都将数据分割两部分,左边小,右边大;
2.按此方法对接着将左和右也递归切分;
3.以此达到整个数据变成有序序列

//快速排序 复杂度最坏为O(n^2)
var arr = [4,9,11,1,3,5,88,22,7,2,5];
function quickSort(arr,l,r){
    if(l < r){
        var p = partition(arr,l,r);
        quickSort(arr,l,p[0]-1);
        quickSort(arr,p[1]+1,r);
    }
}
function partition(arr,l,r){
    var less = l - 1;
    var more = r;
    while(l < more){
        if(arr[l] < arr[r]){
            swap(arr,++less,l++);
        }else if(arr[l] > arr[r]){
            swap(arr,--more,l);
        }else{
            l++;
        }
    }
    swap(arr,more,r);
    return new Array(less+1,more);
}
function swap(arr,i,j){
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
quickSort(arr,0,arr.length-1);
console.log('快排',arr);

调试结果如下:
在这里插入图片描述

荷兰国旗问题
var arr1 = [4,9,11,1,3,5,88,22,7,2];
var arr2 = [3,1,2,4];     
var arr3 = [9,11,55,7];
function partition(arr,l,r,num){
    var less = l - 1;
    var more = r + 1;
    var cur = l;
    while(cur < more){
        if(arr[cur] < num){
            swap(arr,++less,cur++);
        }else if(arr[cur] > num){
            swap(arr,--more,cur);
        }else{
            cur++;
        }
    }
    return arr;
}
function swap(arr,i,j){
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
console.log('arr1',partition(arr1,0,arr1.length-1,5));
console.log('都小于num的arr2',partition(arr2,0,arr2.length-1,5));
console.log('都大于num的arr3',partition(arr3,0,arr3.length-1,5));

调试结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值