数据结构--Javascript--排序篇
1. 直接插入排序(Straight Insertion Sort):
1 /* 2 * 插入排序 3 * O(n^2) 4 * */ 5 Array.prototype.insertSort = function () { 6 var i,j,temp; 7 for(i=2; i<this.length; i++){ 8 //先判断一下,不是递增序列则进行移动插入操作 9 if(this[i] < this[i-1]){ 10 //记录需要进行插入的元素,找到它应该插入的位置 11 temp = this[i]; 12 /* 13 * 边移动边比较,直到找到合适的插入位置 14 for(j=i-1; temp <= this[j]; j--) 15 this[j+1] = this[j]; 16 这样比较会进行一次不必要的比较,因为第一次的比较在上一层if已经做过. 17 */ 18 //直接移动,免去不必要的比较 19 this[i] = this[i-1]; 20 for(j=i-2; temp <= this[j]; j--) 21 this[j+1] = this[j]; 22 this[j+1] = temp; 23 } 24 } 25 return this; 26 }
2. 折半插入(Binary Insertion Sort):
与插入排序相比:这仅仅是减少了关键字间的比较次数,但是对记录的移动次数是不变的.
1 /* 2 * 折半插入 3 * O(n^2) 4 * */ 5 Array.prototype.BInsertSort = function() { 6 var i,j,temp,low,high; 7 for(i=2; i<this.length; i++){ 8 temp = this[i]; //记录当前需比较项 9 low = 1; //指向已排序好的第一个元素 10 high = i-1; //指向已排序好的最后一个元素 11 while(low <= high){ 12 var middle = parseInt((low+high)/2); //折半的位置 13 //插入点在排序好的前半部分 14 if(temp < this[middle]) 15 high = middle - 1; 16 //插入点在排序好的后半部分 17 else 18 low = middle + 1; 19 } 20 //移动插入点以后的每项记录 21 for(j=i-1; j>=high+1; j--) 22 this[j+1] = this[j]; 23 this[high+1] = temp; 24 } 25 return this; 26 }
以上都是基于"插入"并且"移动记录"来实现的排序算法.下面将介绍一些最基本的基于"交换记录"来实现排序的算法.
3. 冒泡排序(Bubble Sort):
1 /* 2 * 冒泡排序 3 * O(n^2) 4 * js内部sort()采用此排序算法? 5 * */ 6 Array.prototype.bubbleSort = function() { 7 //理论上进行n-1趟排序,当某一次排序过程中并没有发生记录交换的时候证明排序已经完成了. 8 //记录是否发生了交换记录的事件 9 var flag = true; 10 for(var i=this.length-1,flag = true; i>0 && flag; --i){ 11 flag = false; 12 for(var j=0; j<i; ++j){ 13 if(this[j] > this[j+1]){ 14 var temp = this[j]; 15 this[j] = this[j+1]; 16 this[j+1] = temp; 17 flag = true; 18 } 19 } 20 } 21 return this; 22 }
4. 2-路归并排序(Merge Sort):
偶然发现网上一牛人这么写的, 不得不佩服把JS用活到这种地步!
1 Array.prototype.mergeSort = function() { 2 3 // result是结果集合 4 var result = [], len = this.length, 5 mid = parseInt( len / 2 ), 6 _left = this.slice( 0, mid ), 7 _right = this.slice( mid ); 8 9 // 私有函数 10 function merge( left, right ) { 11 while ( left.length && right.length ) { 12 result.push( left[0] <= right[0] ? left.shift() : right.shift() ); 13 } 14 15 // 把剩余的元素直接加入 16 return result.concat( left.concat( right ) ); 17 } 18 19 // 当只剩下一位的时候结束 20 if ( len < 2 ) { 21 return this; 22 } 23 24 // 递归的处理代码片段 25 return merge( _left.mergeSort(), _right.mergeSort() ); 26 } 27 28 // example 29 var i = 0, 30 test = []; 31 32 for ( ; i < 50; ++i ) { 33 test.push( Math.floor( Math.random() * 1000 ) ); 34 } 35 36 console.time(''); 37 console.log( test.mergeSort() ); 38 console.timeEnd('');