js实现的各种排序算法

.

数组排序的本质就是在比较数据的大小,看起来简单的大小比较随着数组长度的增加会变的非常繁杂。简单来看,更少的比较次数显然会有更好的性能,反应到编程语言里就是更少的循环次数。下面是我对几种常见排序算法的理解

1.冒泡排序:    

js实现的各种排序算法

/*从小到大的冒泡排序*/
function bubbleSort(array){
    var end = array.length-1;
    while(end>0){/*这一层为循环次数,次数为数组长度-1*/
        for(var i=0;i<end;i++){/*这一层进行比较,从左到右相邻的捉对比较,每循环1次,捉对比较次数少一次*/
            if(array[i]>array[i+1]){
                var md = array[i+1];
                array[i+1] = array[i];
                array[i] = md;
            }
        }
        end--;
    }
}
/**
*要点:
*1.有两层循环比较
*2.外层循环的次数是(数组长度-1次);内层循环次数初始也是(数组长度-1),且每循环1次后自减1。
*3.内层循环的方式是,根据数组元素下标从小到大,相邻两个元素依次捉对比较1次,并进行数值交换,把更大的数值交换给下标更大的元素。
*4.每次内层循环结束都会得到一个最大值,这个最大值也最终会被交换给本次内层循环中下标最大的数组元素。
*5.每次内层循环挑出的最大值都不用再参与下一次内层循环,所以每次内层循环结束后,内层循环次数减1次(因为上次内层循环结束得到的最大值元素不再需要参与比较,即参与比较的数组元素个数会减1)。

*6.上面代码中用一个变量end做为内层和外层共用的循环结束条件比较巧妙,充分利用了算法的两个特点:
    a.内层循环次数、外层循环初始次数相等
    b.内层循环次数(变量end)逐次减1,外层循环条件中的变量(变量end)也是逐次减1
**/

2插入排序

js实现的各种排序算法

/*从小到大插入排序*/
function insertSort(arr){
	var count=arr.length;
	var end=1;/*取无序区最左边的1个元素*/
	while(end<count){
	        var pos=end;
		for(var i=end-1;i>=0;i--){/*拿无序区最左边的元素分别与有序区从右到左的每个元素比较*/
			var temp=arr[i];
			if(arr[pos]<arr[i]){
				arr[i]=arr[pos];
				arr[pos]=temp;
				pos=i;
			}else{
				break;/*适当的中止循环*/
			}
		}
		end++;
	}
	return arr;
}
/**
*1.插入排序算法原理():
    也是两层循环
    根据数组下标先后顺序,从左到右列出所有数组元素,任意取两个相邻元素a,b;
    假设a和a左边的数据为有序区,b和b右边的数据为无序区;
    内层循环:拿无序区的数据e,依照有序区从右到左的次序,逐个与有序区的数据比较,遇到比e更大的数就交换数值,直到在有序区遇到比e更小或者相等的数,结束本轮内层循环
    外层循环:每一个无序区的数据都要执行一次内层循环
    初始取第二个数组元素为a
    
    外层循环的次数是(数组长度-1);
    内层循环的结束条件是:在有序区遇到更小或者相等的数,或者达到本轮最大循环次数
    每次内层循环结束后,有序区的数据个数会增加1个;
    每轮内层循环最大循环次数比前一轮内层循环最大循环次数多1次(实际循环次数则不一定),
**/

3.快速排序

js实现的各种排序算法

function quickSort(arr){
	var count=arr.length;
	if(count<=1) return arr;
	var pos=Math.floor(count/2);/*算出中间位置*/
	var val=arr.splice(pos,1)[0];/*取出中间位置的元素值作为基准值,并从原数组中移除*/

	var left=[];/*存放比基准值小的数*/
	var right=[];/*存放比基准值大的数*/
	for(var i=0;i<arr.length;i++){/*对移除了中间元素的数组从左到右依次取元素与基准值比较*/
		if(arr[i]<=val){
			left.push(arr[i]);
		}else{
			right.push(arr[i]);
		}
	}
	return quickSort(left).concat([val],quickSort(right));/*把左数组、基准值、右数组合并返回*/

}

或者

function quickSort(arr){/*取数组第一个元素为基准值作比较*/
	var count=arr.length;
	if(count<=1) return arr;
	var left=[];
	var right=[];
	for(var i=1;i<count;i++){
		if(arr[0]<arr[i]){
			right.push(arr[i]);
		}else{
			left.push(arr[i]);
		}
	}
	return quickSort(left).concat(arr[0],quickSort(right));
}
/**
*这种算法逻辑比较复杂,但是最快的一种,据说比内置的排序方法sort还要快
*1在数据集之中,选择一个元素作为"基准"(pivot)。
*2所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
*3对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
**/

4.选择排序

function selectSort(array){
	var i=0;
	var count=array.length;
	while(i<count){
		var min=null;
		/*找出无序区的最小值元素*/
		for(var j=i;j<count;j++){
			if( min>array[j] || min===null){
				min=array[j];
				index=j;
			}
		}
		/*把无序区中的最小值和无序区的首元素值交换*/
		if(index !== i){
			var md=array[i];
			array[i]=min;
			array[index]=md;
		}
		i++
	}
	return array;
}
/**
*也是将数组元素划分为无序和有序区,找出无序区中的最小值和无序区的首元素交换,无序区减少1个,循环至最终完成全部排序。
**/

经过chrome浏览器测试发现冒泡排序,插入排序,快速排序,系统的sort排序的性能表现

数组长度在1000时:5ms以内,           5ms以内,         5ms以内                1ms左右

数组长度在2000时: 10ms以内,        10ms~20ms,     10ms~20ms;         10ms以内

数组长度在5000时:  50ms~60ms,     20ms~30ms,     10ms~20ms;         10ms左右

数组长度在10000时:250ms+,            80ms+,              30ms~50ms;        20ms以内

数组长度在50000时:1900ms+,          6000ms+,          少于150ms;           50ms左右

数组长度100000时:                                                     300ms~400ms      100ms以内

数组长度500000时:                                                     4100ms~4300ms  200ms以内

由此可见,系统的sort排序完胜,冒泡排序性能最弱

下面是冒泡排序,插入排序,快速排序,系统的sort排序的性能测试代码:

var start;
var now;
var arr=[];
for(var i=0;i<1000;i++){/*自动生成指定长度的数组*/
	arr.push(random(1,1000));
}
start=+new Date();/*开始排序时间点*/
charu(arr);
//maopao(arr);
//quickSort(arr);
//arr.sort(function(a,b){return a-b;});
now=+new Date();/*排序结束时间点*/
console.log(now-start);

function random(min,max){
	return Math.ceil(Math.random()*(max-min))+min;
}
function maopao(arr){
	var count=arr.length-1;
	var temp=0;
	while(count>0){
		for(var i=0;i<count;i++){
			if(arr[i]>arr[i+1]){
				temp=arr[i];
				arr[i]=arr[i+1];
				arr[i+1]=temp;
			}
		}
		count--;
	}
	return arr;
}
function quickSort(arr){
	var count=arr.length;
	if(count<=1) return arr;
	var left=[];
	var right=[];
	for(var i=1;i<count;i++){
		if(arr[0]>arr[i]){
			left.push(arr[i]);
		}else{
			right.push(arr[i]);
		}
	}
	return quickSort(left).concat(arr[0],quickSort(right));
}


function charu(arr){
	var count=arr.length;
	var pos=1;
	var temp;
	while(pos<count){
		var j=pos;
		for(var i=pos-1;i>=0;i--){
			if(arr[i]>arr[j]){
				temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
				j=i;

			}else{
				break;
			}
		}
		pos++;
	}
	return arr;
}



你可能感兴趣的:(js快速排序,js数组排序)