原生js数组排序

563 阅读2分钟

原生js数组排序

js 排序 以正序为例(即由小到大)

var arr = [0,2,1,4,3,9,6,5,7,8];  // 未排序的数组
var sortArr = null;  // 排序后得到的数组

1 sort排序

sortArr = arr.sort(function (a,b) {
	return a - b 
})

sort是es3增加的数组方法,大家可以放心使用(支持到ie6),但是数组在原数组上进行排序,不生成副本。这个时候我们的sortArr === arr是同一个数组

2 普通for循环排序

function sort (arr) {
    var newArr = [arr[0]];
    var nl = newArr.length;
    var ol = arr.length;
    for (var i = 1; i <= ol - 1; i++) {
        nl = newArr.length;
        for (var j = 0;  j <= nl - 1; j++) {
            if(newArr[j]>=arr[i]){
                newArr.splice(j, 0, arr[i]);
                break;
            }else if(j == nl - 1){
                newArr.push(arr[i])
                    }
                }
           }
	return newArr;
    }
sortArr = sort(arr);

此方法会重新生成一个数组,并对其进行排序,但是缺点是执行效率低,当数据量较大时,强烈不建议使用此方法。

3 二分法排序

function twoSort (arr) {
    var len = arr.length;
    var left = 0, right = 0, point = 0;   //定义三个标记位,point就是最中间的位置
    var nArr = [];
    nArr[0] = arr[0];         //定义一个数组后,把arr中第一个数先赋给nArr
    for(var i=1; i<len; i++){
        left = 0;
        var nLen = nArr.length;
        right = nLen;
        for(var j=0; j<nLen; j++){
            point = Math.floor((left + right)/2);   //取整
                if(nArr[point] < arr[i]){
                        left = point + 1;          //注意必须加1
                }else{
                        right = point;
                }
                if(right == left){        //如果right和left相等就表示找到了插入的位置 ,插入后,跳出循环
                    nArr.splice(left,0,arr[i]);
                    break;
			}
		}
	}
	return nArr;
}
sortArr = sort(arr);

此方法会重新生成一个数组,并对其进行排序,并且执行效率较高,但是代码量比较大。

4 递归二分法排序的两种写法

法1

function recursiveSort1(arr) {
	if (arr.length <= 1) { return arr; }//如果输入数组长度小于等于1,直接返回数组。这也是递归算法的终结部分
		var base = Math.floor(arr.length / 2);//找到中间的基准元素位置
		var baseEle = arr.splice(base, 1)[0];//把基准元素从arr中摘除
		var left = [];
		var right = [];
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] < baseEle) {
			left.push(arr[i]);
		} else {
			right.push(arr[i]);
		}
	}
	return recursiveSort(left).concat([baseEle ], recursiveSort(right));
	//返回递归左右两个部分concat中间元素,这就是结果
};
sortArr = recursiveSort1(arr);

法2

function recursiveSort2(arr) {
	if (arr.length <= 1) { return arr; }//如果输入数组长度小于等于1,直接返回数组。这也是递归算法的终结部分
		var base = Math.floor(arr.length / 2);//找到中间的基准元素位置
		var baseEle = arr[base];//把基准元素从arr中取出
		var left = [];
		var right = [];
	for (var i = 0; i < arr.length; i++) {
		if (i === base) continue;
		if (arr[i] < baseEle) {
			left.push(arr[i]);
		} else {
			right.push(arr[i]);
		}
	}
	return recursiveSort(left).concat([baseEle ], recursiveSort(right));
	//返回递归左右两个部分concat中间元素,这就是结果
};
sortArr = recursiveSort1(arr);

这两种方法会重新生成一个数组,并对其进行排序,并且执行效率较高,代码量比较小。但是法1会改变原数组(剔除原数组中间的一个元素),法2会保留原数组