javascript实现将多个有序数组合并为一个有序数组的算法

假设有这样一个需求,一个数组的子元素全是有序数组,类似:

let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]];

我们希望将上述数组合并为一个有序数组,怎么处理呢?

最简单的方案就是:
将数组整体合并,然后sort排序,代码如下:

let ret=arr.reduce((arr1,arr2)=>arr1.concat(arr2)).sort((a,b)=>a-b);
ret=Array.from(new Set(ret));
console.log(ret);

但是上面的代码没有充分利用数组子元素本身就是有序数组这一特性,我们利用“归并排序”算法,可以大大的提高类似数组的合并排序性能,代码(代码里面有详细注释)如下:

let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]];
// let arr= [[1,2,3]];

function merge(arr){

    //记录每一个数组循环比较时的下标变化
    function filterIndexArr() {
        indexArr=indexArr.filter((item,index)=>{
            return item.count<arr[item.index].length;
        });
    }

    //将每次比较的元素放进一个临时数组里面,取出最小值放入ret
    function pushToArr(arr) {
        let minVal=arr[0].val;
        let increaseArr=[arr[0].index];
        arr.forEach((item,index)=>{
            if (minVal>item.val){
                minVal=item.val;
                increaseArr=[item.index];
            }else if (minVal==item.val && index!=0){
                increaseArr.push(item.index)
            }
        });
        increaseArr.forEach((item)=>{
            let thatItem=item;
            indexArr.forEach((item)=>{
                if (item.index==thatItem){
                    item.count++;
                }
            });
        });
        filterIndexArr();
        ret.push(minVal);
    }

    let ret=[];
    let indexArr=arr.map((item,index)=>{
        return {
            index,
            count:0
        }
    });
    filterIndexArr();

    let compareArr=[];
    while (indexArr.length>1){
        //循环比较每个数组的第一个元素
        compareArr=indexArr.map((item,index)=>{
            return {
                index:item.index,
                val:arr[item.index][item.count]
            }
        });
        pushToArr(compareArr);
    }
    //取出最后不需要比较的数组元素,直接拼接到ret后面
    let remainArr=arr[indexArr[0].index].slice(indexArr[0].count);
    ret=ret.concat(remainArr);
    ret=Array.from(new Set(ret));
    return ret;
}

let ret=merge(arr);
console.log(ret);

由于子数组本身有序,分别记录要被比较数组的下标,循环取出最小值push到ret就可以了,是不是很简单。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值