代码改变世界

javascript 常用算法总结

2012-11-24 23:12  臭小子1983  阅读(789)  评论(0编辑  收藏  举报

  算法是程序的灵魂。虽然在前端的开发环境中排序算法不是很经常用到,但常见的排序算法还是应该要掌握的。我在这里从网上整理了一下常见排序算法的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()方法是用来对数组项进行排序的 ,默认情况下是进行升序排列,实例代码如下:

    var arrA = [6,2,4,3,5,1];
    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);

  //输出结果:

  6,5,4,3,2,1 
  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));