算法是程序的灵魂。虽然在前端的开发环境中排序算法不是很经常用到,但常见的排序算法还是应该要掌握的。我在这里从网上整理了一下常见排序算法的javascript实现,方便以后查阅。
一、归并排序:
1 function merge(left, right){ 2 var result = [], 3 il = 0, 4 ir = 0; 5 6 while (il < left.length && ir < right.length){ 7 if (left[il] < right[ir]){ 8 result.push(left[il++]); 9 } else { 10 result.push(right[ir++]); 11 } 12 } 13 14 return result.concat(left.slice(il)).concat(right.slice(ir)); 15 }
1 function mergeSort(items){ 2 // 结束条件: 数组元素少于2个 3 if (items.length < 2) { 4 return items; 5 } 6 7 var middle = Math.floor(items.length / 2), 8 left = items.slice(0, middle), 9 right = items.slice(middle); 10 11 return merge(mergeSort(left), mergeSort(right)); 12 }
1 function mergeSort2(items){ 2 if (items.length < 2) { 3 return items; 4 } 5 6 var middle = Math.floor(items.length / 2), 7 left = items.slice(0, middle), 8 right = items.slice(middle), 9 params = merge(mergeSort(left), mergeSort(right)); 10 11 params.unshift(0, items.length); 12 items.splice.apply(items, params); 13 return items; 14 }
二、插入排序:
1 function insertionSort(items) { 2 var len = items.length, 3 value, 4 i, 5 j; 6 7 for (i=0; i < len; i++) { 8 value = items[i]; 9 for (j=i-1; j > -1 && items[j] > value; j--) { 10 items[j+1] = items[j]; 11 } 12 items[j+1] = value; 13 } 14 return items; 15 }
三、选择排序:
1 function swap(items, firstIndex, secondIndex){ 2 var temp = items[firstIndex]; 3 items[firstIndex] = items[secondIndex]; 4 items[secondIndex] = temp; 5 } 6 7 function selectionSort(items){ 8 var len = items.length, 9 min; 10 11 for (i=0; i < len; i++){ 12 min = i; 13 for (j=i+1; j < len; j++){ 14 if (items[j] < items[min]){ 15 min = j; 16 } 17 } 18 19 if (i != min){ 20 swap(items, i, min); 21 } 22 } 23 24 return items; 25 }
四、冒泡排序:
1 function swap(items, firstIndex, secondIndex){ 2 var temp = items[firstIndex]; 3 items[firstIndex] = items[secondIndex]; 4 items[secondIndex] = temp; 5 } 6 7 function bubbleSort(items){ 8 var len = items.length, 9 i, j, stop; 10 11 for (i=0; i < len; i++){ 12 for (j=0, stop=len-i; j < stop; j++){ 13 if (items[j] > items[j+1]){ 14 swap(items, j, j+1); 15 } 16 } 17 } 18 19 return items; 20 }
五、快速排序:
例:arr = [30, 19, 7, 59, 2, 16, 4]; 找出数组中间点为59,循环数组,如果小于59存储到left中,否则存储到right中,然后
1 var quickSort = function(arr) { 2 if (arr.length <= 1) { return arr; } 3 var pivotIndex = Math.floor(arr.length / 2); 4 var pivot = arr.splice(pivotIndex, 1)[0]; 5 var left = []; 6 var right = []; 7 for (var i = 0; i < arr.length; i++){ 8 if (arr[i] < pivot) { 9 left.push(arr[i]); 10 } else { 11 right.push(arr[i]); 12 } 13 } 14 return quickSort(left).concat([pivot], quickSort(right)); 15 };
六、二分法查找:
1 function binarySearch(items, value){ 2 var startIndex = 0, 3 stopIndex = items.length - 1, 4 middle = Math.floor((stopIndex + startIndex)/2); 5 6 while(items[middle] != value && startIndex < stopIndex){ 7 8 if (value < items[middle]){ 9 stopIndex = middle - 1; 10 } else if (value > items[middle]){ 11 startIndex = middle + 1; 12 } 13 14 middle = Math.floor((stopIndex + startIndex)/2); 15 } 16 17 return (items[middle] != value) ? -1 : middle; 18 }
七、基数排序:
1 var countSort = function(array) { 2 var i, z = 0, count = [], 3 min = Math.min.apply({}, array), 4 max = Math.max.apply({}, array), 5 size = array.length; 6 //给新数组预填为零 7 for (i = min; i <= max; i++) { 8 count[i] = 0; 9 } 10 for (i=0; i < size; i++) { 11 count[array[i]]++; 12 } 13 14 for (i = min; i <= max; i++) { 15 while (count[i]-- > 0) {//循环新数组,如果不为零,则把i返回array 16 array[z++] = i; 17 } 18 } 19 return array; 20 }
八、希尔排序:
function shellSort(array) { var j, i, v, h=1, s=3, k,n = array.length; var result = ""; var count = 0; while(h < n) h=s*h+1; while(h > 1) { h=(h-1)/s; for (k=0; k<h; k++) for (i=k+h,j=i; i<n; i+=h, j=i) { v=array[i]; while(true) if ((j-=h) >= 0 && array[j] > v) array[j+h]=array[j]; else break; array[j+h]=v; } count++; result += "<br />第" + count + "遍排序的结果是:"; for (var n = 0; n < array.length; n++) { result += array[n] + ","; } } return result; }
九、组合排序:
1 var combSort = function(array){ 2 var gap = array.length; 3 do{ 4 gap = gap * 10 / 13 5 if(gap === 9 || gap === 10) 6 gap = 11 7 if(gap < 1){ 8 gap = 1 9 } 10 var swapped = false; 11 for(var i=0;i<array.length-gap;i++){ 12 var j = i + gap 13 if(array[i]>array[j]){ 14 var temp = array[i]; 15 array[i] = array[j]; 16 array[j] = temp; 17 test(array) 18 swapped = true 19 } 20 } 21 if(gap == 1 && !swapped){ 22 break; 23 } 24 }while(1); 25 }
十、鸡尾酒排序:
1 var cocktailSort= function(array) { 2 var top = array.length - 1, bottom = 0,flag = true,i, j; 3 while (flag) { 4 flag = false; 5 //从左到右到大,把最大的放到每次范围的最右边 6 for (i = bottom; i < top; i++) { 7 if (array[i] > array[i + 1]) { 8 swap(array, i, i + 1); 9 flag = true; 10 } 11 } 12 top--; 13 //从右到到左,把最小的放到每次范围的最小边 14 for (j = top; j > bottom; j--) { 15 if (array[j] < array[j - 1]) { 16 swap(array, j, j - 1); 17 flag = true; 18 } 19 } 20 bottom++; 21 } 22 } 23 24 var swap = function(array,a,b){ 25 var tmp = array[a]; 26 array[a] = array[b] 27 array[b] = tmp; 28 }
二、js数组 sort方法的分析
javascript 中 Array.sort()方法是用来对数组项进行排序的 ,默认情况下是进行升序排列,实例代码如下:
arrA.sort();
document.writeln(arrA);
//结果是:1,2,3,4,5,6
sort() 方法可以接受一个 方法为参数 ,这个方法有两个参数。分别代表每次排序比较时的两个数组项。sort()排序时每次比较两个数组项都回执行这个参数,并把两个比较的数组项作为参数传递给这个函数。当函数返回值为1的时候就交换两个数组项的顺序,否则就不交换。
实例如下:
1 var arrA = [6,2,4,3,5,1]; 2 /*arrA.sort(); 3 document.writeln(arrA); 4 */ 5 6 function desc(x,y) 7 { 8 if (x > y) 9 return -1; 10 if (x < y) 11 return 1; 12 } 13 function asc(x,y) 14 { 15 if (x > y) 16 return 1; 17 if (x < y) 18 return -1; 19 } 20 21 arrA.sort(desc); // sort by desc 22 document.writeln(arrA); 23 document.writeln("<br>"); 24 arrA.sort(asc); //sort by asc 25 document.writeln(arrA);
//输出结果:
1,2,3,4,5,6
另外,可以直接把一个无名函数直接放到sort()方法的调用中。如下的例子是将奇数排在前面,偶数排在后面,例子如下:
1 var arrA = [6,2,4,3,5,1]; 2 arrA.sort( function(x, y) { 3 if (x % 2 ==0) 4 return 11; 5 if (x % 2 !=0) 6 return -1; 7 } 8 ); 9 document.writeln(arrA);
//输出:1,5,3,4,6,2
二、排列组合
从1-10的数中取出六个数字,能排列出多少组不同的顺序
C10 6公式:(1*2*3*4*5*6*7*8*9*10)/((1*2*3*4)*(1*2*3*4*5*6))
1 <script> 2 function arrangement(total, target){ // @total:总的排列数 @target:组合的总数 3 var nTotal = 1; 4 var nTarget = 1; 5 var nNum = 1; 6 7 for(var i=1; i<=total; i++){ 8 nTotal *= i; 9 } 10 11 for(var k=1, tar=total-target; k<=tar; k++){ 12 console.log(tar); 13 nTarget *= k; 14 } 15 16 for(var s=1; s<=target; s++){ 17 nNum *= s; 18 } 19 20 console.log(nTotal,nTarget,nNum) 21 22 return nTotal/(nTarget*nNum); 23 } 24 25 var result = arrangement(16, 6); 26 console.log(result); 27 </script>
三、冒泡排序
原理:
较相邻的元素。如果第一个比第二个大,就交换他们两个。
用两个循环分别取出第一个数和第二个数,然后做比较如果小于或者大于就将通过一个变量将两个位置互换,并跳出循环,进行下一个数的比较
1 <script> 2 var arr = [2,434,7,9,200,11,23,46,238,45,0,67,3,32,12,32,444,555,666,775,443]; 3 var len = arr.length; 4 var nMax = 0; 5 6 function bubbleSort(array){
var i = 0, len = array.length, j, d; 9 for(i; i<len; i++){ 10 for(j=0; j<len; j++){ 11 if(array[i] < array[j]){ // 冒泡从高到低 12 d = array[j]; 13 array[j] = array[i]; 14 array[i] = d; 15 break; 16 } 17 } 18 }
return array; 21 } 22 23 var getSort = bubbleSort(arr); 24 document.write(getSort); 25 </script>
四、计算百分比
胜200 平10 负40 各占的百分比
公式:数量 / 总数 * 100
求200占的百分比就是 200/250*100=80%
1 // 保留两位小数 2 // @num:数量 @sum:总数 3 function ratio(num, sum){ 4 if(!num || !sum){ 5 return ; 6 } 7 var nVal = num / sum * 100; 8 return nVal.toFixed(2); 9 }
五、一组数中有多少个重复的数,并重复了多少次
1 <script> 2 var arr=[1, 3, 1, 3, 3, 2, 5, 6, 7, 5, 4, 3]; 3 var json={}; 4 5 for(var i=0; i<arr.length; i++){ 6 var ret = arr[i]; 7 if(!json[ret]){ 8 json[ret]=1; 9 } 10 else { 11 json[ret]++; 12 } 13 }; 14 15 for(var i in json){ 16 alert('"'+i+'"出现了:'+json[i]+'次') 17 }; 18 </script>
六、表格排序
1 <script> 2 /* 3 * 思路: 4 * 1、先获取所有tr的指针(DOM元素) 5 * 2、通过sort进行排序 6 * 3、排序后的指针重新 7 * */ 8 9 function sortTabel(){ 10 var oTab = $("#tab tbody"); 11 var oArr = []; 12 oTab.find("tr").each(function(){ 13 oArr.push($(this)); 14 }) 15 16 // console.log(oArr); 17 oArr.sort(generateCompareTRs("des")); 18 19 console.log(oArr); 20 $.each(oArr, function(i){ 21 oTab.append(oArr[i]); 22 }) 23 } 24 25 function generateCompareTRs(type){ 26 return function compareTRs(t1,t2){ 27 var v1 = parseInt(t1.find("td:eq(0)").text()); // 获取比较列的号 28 var v2 = parseInt(t2.find("td:eq(0)").text()); 29 30 if(type==="des"){ // 降序 31 if(v1>v2){ 32 return 1; 33 } 34 else{ 35 return -1; 36 } 37 } 38 if(type==="asc"){ // 升序 39 if(v1>v2){ 40 return -1; 41 } 42 else{ 43 return 1; 44 } 45 } 46 } 47 } 48 49 $("body").click(function(){ 50 sortTabel() 51 }); 52 </script>
七、数组去重的四种方法
方法一:推荐使用,通过添加到对象中,在查看是否存在
1 function remRepeatArr(arr){ 2 console.time("b"); 3 if(arr.length < 1){ 4 return false; 5 } 6 7 var arr = arr; 8 var tempArr = []; 9 var obj = {}; 10 for(var i= 0, len=arr.length; i<len; i++){ 11 obj[arr[i]] = 0; 12 } 13 14 for(var key in obj){ 15 tempArr.push(key); 16 } 17 18 console.timeEnd("b"); 19 return tempArr; 20 } 21 22 var ss = remRepeatArr([1,45,423,453,2,1,236,68,9,3,457,678,323,3,45,67,7,88,93,2,4]); 23 console.log(ss);
方法二:双重循环去匹配每个数,效率慢些
1 function delRepeatArr(arr){ 2 var res = [arr[0]]; 3 for(var i = 1; i < arr.length; i++){ 4 var repeat = false; 5 for(var j = 0; j < res.length; j++){ 6 if(arr[i] == res[j]){ 7 repeat = true; 8 break; 9 } 10 } 11 if(!repeat){ 12 res.push(arr[i]); 13 } 14 } 15 return res; 16 } 17 18 var arr = [112,112,34,'你好',112,112,34,'你好','str','str1']; 19 console.log(delRepeatArr(arr));
方法三:
1 function delRepeatArr(arr){ 2 arr.sort(); //先排序 3 var res = [arr[0]]; 4 for(var i = 1; i < arr.length; i++){ 5 if(arr[i] !== res[res.length - 1]){ 6 res.push(arr[i]); 7 } 8 } 9 return res; 10 } 11 12 var arr = [112,112,34,'你好',112,112,34,'你好','str','str1']; 13 console.log(delRepeatArr(arr));