归并排序的实现

原理

归并的意思是将两个有序的线性表组合成一个新的有序线性表。是基于分治思想的排序算法,它在递归到对数组的l到r的位置之间的数进行排序时,首先根据中间位置 mid=(l+r)/2 分成两半,然后递归分别对左边一半和右边一半进行归并排序,最后对两个已排序好的一半进行合并。(稳定)
其中主要的部分是对两个有序数组的合并,复杂度为O(n)。以下将合并的部分代码专门写成一个函数

function merge1(arr, left, mid, right) {
    // 两个数组: arr[left..mid], arr[mid+1..right], 都是有序的
    var n = right-left+1; // 两个数组的总长度
    var temp = []; // 用来储存元素的临时数组
    var l = left, r = mid+1; // 用两个指针分别遍历两个数组
    while (l <= mid && r <= right){ // 在指针都在数组范围内时
        // 比较两个指针指向的元素,把较小的一个放进temp,然后指针+1
        if (arr[l] <= arr[r]) {
            temp.push(arr[l++]);
        } else {
            temp.push(arr[r++]);
        }
    }
    // 循环结束后,肯定有一个数组已经遍历完成,将另一个数组的剩余元素全都加入temp
    while (l <= mid) {
        temp.push(arr[l++]);
    } 
    while (r <= right) {
        temp.push(arr[r++]);
    } 
    // 完成后temp是有序的,这时候把它的元素copy回arr数组的对应位置(left-right)
    for (var k = 0; k < n; k++) {
        arr[left+k] = temp[k]; // copy back
    } 
}

function mergeSort(arr, left, right) {
    if (left < right) {
        var mid = Math.floor((left+right) / 2);  // 留意js这里需要处理成整数
        mergeSort(arr, left, mid); 
        mergeSort(arr, mid+1, right); 
        merge2(arr, left, mid, right); 
    }
}

其中,对于merge部分,遍历两个数组合并成一个,还有一个代码更少但理解起来略微复杂的写法:

function merge2(arr, left, mid, right) {
    var n = right-left+1;
    var temp = []; 
    var l = left, r = mid+1;
    while (l <= mid || r <= right) {
        if (l <= mid && (r > right || arr[l] <= arr[r])) {
            temp.push(arr[l++]);
        }else {
            temp.push(arr[r++]);
        }
    }
    for (var k = 0; k < n; k++) {
        arr[left+k] = temp[k]; 
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值