zoukankan      html  css  js  c++  java
  • 有序数组的连接问题

           昨天碰到一道关于如何解决有序数组的连接问题,这是一个很常见的问题。但是这里要考虑到代码的效率问题,因为要连接的数组都是有序的,这是一个非常重要的前提条件。

    2.简单但效率不高的算法

     我首先想到的是使用内置的concat方法,然后再对其进行排序,这种方法完全没有考虑到数组是有序的前提条件,代码如下:

    function concatSort(arrA,arrB){
         return arrA.concat(arrB).sort();
    }
    

       为了弄清楚sort排序到底使用的是什么算法,特地到看了V8引擎的算法(链接:这里),大概意思是当数组的长度较短的时候使用的是插入排序(InsertionSort),当数组的长度较长的时候使用的是快速排序(QuickSort)。纠正了自己长时间来的一个误区,一直以为sort使用的是冒泡。

    3. 取小值插入的方法

     大概思路:就是同时对两个数组进行遍历,设置两个标志(i,j)用于记录遍历的位置,将两个数组中较小的那个值插入新数组中,接着再将标志往前移动一个位置,重复比较,直到搜索值都插入到数组中。第一次做的时候判断条件写错了,所以出现了死循环,暴露了自己算法能力还是挺薄弱的。

    function mergeArr(arrA,arrB){
       var i , j , k, lenA = arrA.length, lenB = arrB.length , allLen = lenA + lenB,result = [];
       for(i=0,j=0,k =0; k < allLen; k++ ){
           if(i < lenA &&(j >= lenB || arrA[i] < arrB[j])){
               result.push(arrA[i++]); 
           }else{
                result.push(arrB[j++]);
           }
       }
       return result;
    }
    var a = [1,2,4], b = [3,5,6,7,10];
    console.log(con(a,b));  //[1,2,3,4,5,6,7,10]
    

      

    将这个算法与上面的方法1,在jsperf进行性能对比,发现第二种算法的效率明显优于第一种。不相信就猛击这里

    4.问题升级:增加合并数组的数量

      假如增加数组的个数,;例如 A = [1,5],B = [2,6],C = [3,4].......K = [....],求合并的数组。    

         悔恨当初没学好数据结构,最后选择放弃。面试完后想了想,抠出这么一个方法,代码如下:   

    function mergeSort(){
        var i ,len = arguments.length , result = arguments[0];
        for(i=1 ; i< len; i++){
            result = mergeArr(result,arguments[i]);
        }
        return result;
    }
    function mergeArr(arrA,arrB){
       var i , j , k, lenA = arrA.length, lenB = arrB.length , allLen = lenA + lenB,result = [];
       for(i=0,j=0,k =0; k < allLen; k++ ){
           if(i < lenA &&(j >= lenB || arrA[i] < arrB[j])){
               result.push(arrA[i++]); 
           }else{
                result.push(arrB[j++]);
           }
       }
       return result;
    }
    var a = [1,4,7], b = [2,5,8], c = [3,6,9,10];
    console.log(mergeSort(a,b,c));  // [1,2,3,4,5,6,7,8,9,10]
    

      

    5、上述4算法的改进

         上述4的算法需要合并很多次,也就是需要执行mergeArr()的次数为n-1次,其中n为待合并数组的个数,这样的效率实在是不敢恭维。那就加速合并的速度,受2路归并算法的启发,将代码调整如下:

    function mergeSort(arr){
        var i , len = arr.length ,temp = [];
        if(len === 1){
            return arr[0];
        }
        for(i=0; i<len; i+=2){
            if(i+1 < len){
                temp.push( mergeArr(arr[i],arr[i+1]) );
            }else{
                temp.push(arr[i]);
            }
        }
        return mergeSort(temp);
    }
    function mergeArr(arrA,arrB){
       var i , j , k, lenA = arrA.length, lenB = arrB.length , allLen = lenA + lenB,result = [];
       for(i=0,j=0,k =0; k < allLen; k++ ){
           if(i < lenA &&(j >= lenB || arrA[i] < arrB[j])){
               result.push(arrA[i++]); 
           }else{
                result.push(arrB[j++]);
           }
       }
       return result;
    }
    

      将4、5用到的算法在jsperf上进行测试,发现效率提高了不少,猛击这里看结果: 这里

  • 相关阅读:
    MYSQL索引
    MYSQL 外键 on语句 多表查询
    MYSQL用户管理
    MYSQL数据类型 表基本操作 表记录增删改 单表查询
    JQuery 引用方式
    JQuery 元素操作 each循环
    Android EditText方框验证码 短信验证码攻略
    android MVP模式介绍与实战
    一些不错的Android开源音视频播放器
    Android可伸缩布局-FlexboxLayout(支持RecyclerView集成)
  • 原文地址:https://www.cnblogs.com/shamoguying1140/p/3348378.html
Copyright © 2011-2022 走看看