js排序算法总结—冒泡,快速,选择,插入,希尔,归并

相信排序是任何一个程序猿都会用到的东西,今天简单总结记录下常见的排序算法。

 

一.冒泡排序

     说起冒泡排序,可能每个人都不会陌生,实现思路相当简单明了,就是不停的对数组进行两两比较,将较大(较小)的一项放在前面;

     如 var arr = [7, 3, 10, 1, 8, 4, 2, 4, 4, 3] 进行升序排列,排序过程如下

     第一次 [3, 7, 1, 8, 4, 2, 4, 4, 3, 10]

     第二次 [3, 1, 7, 4, 2, 4, 4, 3, 8, 10]

     以此类推 。。。。

     结果 [1, 2, 3, 3, 4, 4, 4, 7, 8, 10];

//冒泡排序
function bubbleSort(arr){
  var len = arr.length,t
  for(j=0;j<=len-1;j++){
      for(i=0;i<=len-j-1;i++){
          if(arr[i]>arr[i+1]){
             t = arr[i+1];
             arr[i+1] = arr[i];
             arr[i] = t;     
          }    
      }
  }
  return arr;
}

 

二.快速排序

      快速排序也是我们常用到的一种排序方式,核心步骤如下

          1.选择中间数。

          2.构建两个临时数组,比中间数小的放到左边,大的放到右边

          3.对临时数组重复1-2;

     例如,我们原始数组为[2,4,1,5,6,3,12,9,7],第一步我们选择第5项 6 为中间数,创建临时数组left,right,则left 结果为[2,4,1,5,3],right 结果为 [12,9,7]。然后再分别对left和right进行相同的操作,直至left及right数组长度为1.

具体代码如下:

//快速排序
function quickSort(arr){
    if(arr.length <= 1){   //数组长度为1时,则停止递归
        return arr    
    }
    var l = Math.floor(arr.length/2);  //选择中间数
    var left = [],right=[];
    var splitEle = arr.splice(l,1)[0]  //将中间数从原数组删除并保存
    for(i=0;i<arr.length;i++){
        if(arr[i] < splitEle){
            left.push(arr[i])
        }else{
            right.push(arr[i])
        }
    }
    return arguments.callee(left).concat(splitEle,arguments.callee(right))
}

 

 

三.选择排序

      选择排序核心思想如下:

      加入我们进行升序排列,我们假设数组第一项为最小值,然后将第一项与其他项分别比较,如果其他项小于第一项,则交换位置,这样第一次循环结束我们可以保证第一项为最小值。然后第二项做类似操作,然后以此类推,具体如下图所示

     

      代码如下:

//选择排序
function selectQuot(arr){
    for(i=0; i<arr.length-1; i++){
        for(j=i+1;j<arr.length;j++){
            if(arr[i] > arr[j]){
                var temp;
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr
}

 

四.插入排序

      插入排序很好理解,首先我们取出第一项放入一个虚构的数组,然后取第二项,假如第二项小于第一项,则将第二项放于第一项的前面,否则放在后面;然后取第三项,分别与前两项进行比较(是不是有点儿类似打扑克牌~~)

     如我们的数组为[2, 4, 1, 5, 3, 8 ,7 ,9 , 6];

     假定我们有一个虚拟数组,则第一步数组为[2],然后我们取数组的第二项,发现要比刚才取得数组项大,则我们放在后面即虚拟数组变成[2,4],然后取下一项与虚拟数组中的项分别比较,按上述思路结果为[1,2,4],以此类推……当然在实际编程中我们并不需要单独创建数组。

     代码如下:

//插入排序
function insertSort(arr){
    for(i=1 ; i<arr.length ; i++ ){
        var temp =  arr[i],
            j = i - 1;
        while(j>=0 && temp < arr[j]){
            arr[j+1] = arr[j];   //相当于将虚拟数组当前项后移一位,同时虚拟数组长度+1
            j--;
        }
        arr[j+1] = temp; //新加项最终插入的位置
    }
    return arr;
}

 

五.希尔排序

      希尔排序是插入排序的升级版,又称为缩小增量排序。

      对于插入排序算法来说,如果原来的数据就是有序的,那么数据就不需要移动,基于此,希尔排序首先将数组按照一定间隔分为若干个小数组分别进行插入排序,然后逐渐减小间隔,直至为1,这样最后一次处理即间隔为1的排序,但由于之前的操作后数组基本变为有序数组,这样就能提高些效率。示意如下:

      我们原始数组为[3, 4, 6, 5, 1, 9, 6, 10, 8, 8]

      第一步我们假设增量为3,按照希尔排序思路我们将数组如下分割

      

     我们每一次将同样的分组赋予同一颜色,然后对每一分组进行插入排序,空白颜色为结果。

     实现代码如下:

//希尔排序
function shellSort(array) {
    var len = array.length;
    var gap = len;
    do {
        gap = Math.floor(gap/3)+1; // 减小增量
        // 把距离为gap的元素编为一个组,扫描所有组
        for (var i = gap; i < len; i++) {
           var  temp = array[i],
                j = i - gap;
           while(j>=0 && temp < array[j]){
               array[j + gap] = array[j];
               j -= gap;
           }
           array[j+gap] = temp; 
        }
    }while(gap > 1)
    return array
}

 

六.归并排序

      归并排序的核心思想是,首先将数组分成若干个子数组变成有序数组,再合并有序数组。

      具体流程盗用网络上一张图,一看便知

      代码如下:

var mergeSort = {
    splitArr : function(arr){
        if(arr.length == 1) return arr;
        var mid = Math.floor(arr.length/2),
            left = arr.slice(0,mid),
            right = arr.slice(mid);
        return this.merge(this.splitArr(left),this.splitArr(right))
    },
    merge : function(left , right){
        var result = [];
        while(left.length > 0 && right.length > 0){
            if(left[0] < right[0]){
                result.push(left.shift())
            }else{
                result.push(right.shift())
            }    
        }
        return result.concat(left).concat(right)
    }
}

      如果您觉得文章对您有帮助,请帮忙点击右下角的推荐,文中不足之处也欢迎指出以便及时改正。

posted @ 2016-10-14 13:16  走在起点  阅读(856)  评论(1编辑  收藏  举报