原生JS排序算法的优化

问题举例:

当我们遇到这样一个排序问题:一个班级随机站成一排,现在需要从低到高重新排一下。做法是:从第二个开始依次跟其前面一个人比较高矮,高的向后。如:1,6,5,8,7,4,3,2-->1,5,6,8,7,4,3,2-->1,5,6,7,8,4,3,2-->1,5,6,7,4,8,3,2-->1,5,6,4,7,8,3,2   ...  -->1,2,3,4,5,6,7,8

JS算法实现:

var sort=function(oArray){
    var array=oArray;
    var i, j,value,n=array.length;
    for(j=1;j;j++){
        i=j-1;
        value=array[j];
        while(i>=0 && array[i]>value){
            array[i+1]=array[i];
            i--;
        }
        array[i+1]=value;
    }
    return array;
};

测试:

原数组

[5,55,4,8,5,2,1,89,2,23,15,6,89,6,14,23,74];

将会得到

Array[17]1 2  2 4 5 5 6 6 8 14 15 23 23 55 74 89 89

有问题?
当一个项目中,需要对比的数组中,元素不是number类型。
比如:一个小区是一个数组,每个数组成员都是一栋楼,而楼是一个对象(每层楼都是一个属性)或者楼本身也是一个数组,我们希望按照楼高由低到高排序(数组中元素的长度排序或者对象元素的属性多少排序)。
当多个需求同时存在的时候,我们希望可以通过一套代码满足string(长度排序) number(大小排序) array(长度排序) object(属性多少排序)。
代码优化:
var compare=function(a,b){
    if(typeof (a)===typeof (b)){
        switch (typeof (a)){
            case 'number':
                return a>b;
                break;
            case 'boolean':
                return a==true;
                break;
            case 'string':
                if(a.length != b.length)return a.length> b.length ;
                return a>b;
            case 'object':
                if(Object.prototype.toString.call(a)===Object.prototype.toString.call(b)){
                    if(Object.prototype.toString.call(a)=='[object Array]')return a.length> b.length;
                    function getCount(obj){
                        var n, count = 0;
                        for(n in obj){if(obj.hasOwnProperty(n))count++;}
                        return count;
                    }
                    return getCount(a)>getCount(b);
                }
                else return false;
                break;
            default :
                return false;
        }
    }
else return true;
}
var optimizeSort=function(oArray){
    var array=oArray;
    var i, j,value,n=array.length;
    for(j=1;j;j++){
        i=j-1;
        value=array[j];
        while(i>=0 && compare(array[i],value)){
            array[i+1]=array[i];
            i--;
        }
        array[i+1]=value;
    }
    console.log(array);
    return array;
};
优化的方案仅仅是正对于相同类型。对不同类型的比较思路一样,此处不作赘述。
compare=function(a,b)
compare方法提供了两个元素的大小比较。
typeof (a)===typeof (b)
判断类型是否相同( 需要注意的是此处无法判断array和object,使用typeof这两者均返回object),number类型直接比较大小,boolean类型此处是认为true>=0所以默认设为了false排在true前,string类型首先对比长度,长度相同时依次比较靠前的字符的ASCII码
当typeof返回'object'时:
Object.prototype.toString.call(a)===Object.prototype.toString.call(b)
判断是否同为array或者同为object
同为object:
getCount(obj)
获取object的属性数量。需要注意的是需要清除有些属性属于继承而来并非我们定义的属性,排除方法如下:
 
   
if(obj.hasOwnProperty(n))
同为array:
直接对比长度

本文所述算法比较基础,希望能起到抛砖引玉作用,并为之后渐渐深入的JS算法博文作铺垫。
以上是个人总结的使用js实现兼容多个数据类型的排序算法。上述缺少对不同类型的对比,这类情况,大家可以自己研究。
本专题的下一篇博客将会介绍JS实现另一种常用的算法,算法会由简单渐渐深入。
update   by   yezhen                      nanjing/2017/03/11

(如有优化建议,欢迎指正)

你可能感兴趣的:(经典算法的JS实现)