JavaScript希尔排序、快速排序、归并排序算法


Posted in Javascript onMay 08, 2016

以var a = [4,2,6,3,1,9,5,7,8,0];为例子。

1.希尔排序。 希尔排序是在插入排序上面做的升级。是先跟距离较远的进行比较的一些方法。

function shellsort(arr){ 
  var i,k,j,len=arr.length,gap = Math.ceil(len/2),temp; 
  while(gap>0){ 
    for (var k = 0; k < gap; k++) { 
      var tagArr = []; 
      tagArr.push(arr[k]) 
      for (i = k+gap; i < len; i=i+gap) {        
        temp = arr[i]; 
        tagArr.push(temp); 
        for (j=i-gap; j >-1; j=j-gap) { 
          if(arr[j]>temp){ 
            arr[j+gap] = arr[j]; 
          }else{ 
            break; 
          } 
        } 
        arr[j+gap] = temp; 
      } 
      console.log(tagArr,"gap:"+gap);//输出当前进行插入排序的数组。 
      console.log(arr);//输出此轮排序后的数组。 
    } 
    gap = parseInt(gap/2); 
  } 
  return arr; 
}

过程输出:

[4, 9] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[2, 5] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[6, 7] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[3, 8] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[1, 0] "gap:5" 
[4, 2, 6, 3, 0, 9, 5, 7, 8, 1] 
[4, 6, 0, 5, 8] "gap:2" 
[0, 2, 4, 3, 5, 9, 6, 7, 8, 1] 
[2, 3, 9, 7, 1] "gap:2" 
[0, 1, 4, 2, 5, 3, 6, 7, 8, 9] 
[0, 1, 4, 2, 5, 3, 6, 7, 8, 9] "gap:1" 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

由输出可以看到。第一轮间隔为5。依次对这些间隔的数组插入排序。
间隔为5:

[4, 9] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[2, 5] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[6, 7] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[3, 8] "gap:5" 
[4, 2, 6, 3, 1, 9, 5, 7, 8, 0] 
[1, 0] "gap:5" 
[4, 2, 6, 3, 0, 9, 5, 7, 8, 1] 
[4, 6, 0, 5, 8] "gap:2" 
[0, 2, 4, 3, 5, 9, 6, 7, 8, 1] 
[2, 3, 9, 7, 1] "gap:2" 
[0, 1, 4, 2, 5, 3, 6, 7, 8, 9] 
[0, 1, 4, 2, 5, 3, 6, 7, 8, 9] "gap:1" 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

间隔为2:

[4, 2, 6, 3, 0, 9, 5, 7, 8, 1] 
 4   6   0   5   8 
  2   3   9   7   1

排序后:
[0, 1, 4, 2, 5, 3, 6, 7, 8, 9] 

间隔为1:
排序后:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。

2.快速排序。把一个数组以数组中的某个值为标记。比这个值小的放到数组的左边,比这个值得大的放到数组的右边。然后再递归 对左边和右边的数组进行同样的操作。直到排序完成。通常以数组的第一个值为标记。
代码:

function quickSort(arr){ 
  var len = arr.length,leftArr=[],rightArr=[],tag; 
  if(len<2){ 
    return arr; 
  } 
  tag = arr[0]; 
  for(i=1;i<len;i++){ 
    if(arr[i]<=tag){ 
      leftArr.push(arr[i]) 
    }else{ 
      rightArr.push(arr[i]); 
    } 
  } 
  return quickSort(leftArr).concat(tag,quickSort(rightArr)); 
}

3.归并排序。把一系列排好序的子序列合并成一个大的完整有序序列。从最小的单位开始合并。然后再逐步合并合并好的有序数组。最终实现归并排序。
合并两个有序数组的方法:

function subSort(arr1,arr2){ 
 
  var len1 = arr1.length,len2 = arr2.length,i=0,j=0,arr3=[],bArr1 = arr1.slice(),bArr2 = arr2.slice(); 
 
  while(bArr1.length!=0 || bArr2.length!=0){ 
    if(bArr1.length == 0){ 
      arr3 = arr3.concat(bArr2); 
      bArr2.length = 0; 
    }else if(bArr2.length == 0){ 
      arr3 = arr3.concat(bArr1); 
      bArr1.length = 0; 
    }else{ 
      if(bArr1[0]<=bArr2[0]){ 
        arr3.push(bArr1[0]); 
        bArr1.shift(); 
      }else{ 
        arr3.push(bArr2[0]); 
        bArr2.shift(); 
      } 
    } 
  } 
  return arr3; 
}

归并排序:

function mergeSort(arr){ 
  var len= arr.length,arrleft=[],arrright =[],gap=1,maxgap=len-1,gapArr=[],glen,n; 
  while(gap<maxgap){ 
    gap = Math.pow(2,n); 
    if(gap<=maxgap){ 
      gapArr.push(gap); 
    } 
    n++; 
  } 
  glen = gapArr.length; 
  for (var i = 0; i < glen; i++) { 
    gap = gapArr[i]; 
    for (var j = 0; j < len; j=j+gap*2) { 
      arrleft = arr.slice(j, j+gap); 
      arrright = arr.slice(j+gap,j+gap*2); 
      console.log("left:"+arrleft,"right:"+arrright); 
      arr = arr.slice(0,j).concat(subSort(arrleft,arrright),arr.slice(j+gap*2)); 
    } 
  } 
  return arr; 
}

排序[4,2,6,3,1,9,5,7,8,0]输出:

left:4 right:2 
left:6 right:3 
left:1 right:9 
left:5 right:7 
left:8 right:0 
left:2,4 right:3,6 
left:1,9 right:5,7 
left:0,8 right: 
left:2,3,4,6 right:1,5,7,9 
left:0,8 right: 
left:1,2,3,4,5,6,7,9 right:0,8

看出来从最小的单位入手。
第一轮先依次合并相邻元素:4,2;  6,3; 1,9; 5,7; 8,0
合并完成之后变成: [2,4,3,6,1,9,5,7,0,8]
第二轮以2个元素为一个单位进行合并:[2,4],[3,6];    [1,9],[5,7];    [0,8],[];
合并完成之后变成:[2,3,4,6,1,5,7,9,0,8]
第三轮以4个元素为一个单位进行合并:[2,3,4,6],[1,5,7,9];  [0,8],[]
合并完成之后变成: [1,2,3,4,5,6,7,9,0,8];
第四轮以8个元素为一个单位进行合并: [1,2,3,4,5,6,7,9],[0,8];
合并完成。 [0,1,2,3,4,5,6,7,8,9];

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
Jquery:ajax实现翻页无刷新功能代码
Aug 05 Javascript
jquery利用命名空间移除绑定事件的方法
Mar 11 Javascript
JQuery查找DOM节点的方法
Jun 11 Javascript
轮播图组件js代码
Aug 08 Javascript
JS获取一个未知DIV高度的方法
Aug 09 Javascript
chrome浏览器如何断点调试异步加载的JS
Sep 05 Javascript
bootstrap table服务端实现分页效果
Aug 10 Javascript
JS运动特效之完美运动框架实例分析
Jan 24 Javascript
脚手架vue-cli工程webpack的作用和特点
Sep 29 Javascript
浅析Vue.js 中的条件渲染指令
Nov 19 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
Nov 20 Javascript
详解微信小程序图片地扯转base64解决方案
Aug 18 Javascript
基于jquery实现最简单的选项卡切换效果
May 08 #Javascript
基于javascript实现图片滑动效果
May 07 #Javascript
基于jquery实现图片放大功能
May 07 #Javascript
基于bootstrap插件实现autocomplete自动完成表单
May 07 #Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
May 07 #Javascript
js实现上传图片及时预览
May 07 #Javascript
Backbone.js框架中Model与Collection的使用实例
May 07 #Javascript
You might like
javascript 防止刷新,后退,关闭
2010/08/07 Javascript
javascript Array.prototype.slice使用说明
2010/10/11 Javascript
js 获取和设置css3 属性值的实现方法
2013/05/06 Javascript
使用微信内置浏览器点击下拉框出现页面乱跳转现象(iphone),该怎么办
2016/01/04 Javascript
Vue.js实现一个自定义分页组件vue-paginaiton
2016/09/05 Javascript
js变量提升深入理解
2016/09/16 Javascript
正则表达式替换html元素属性的方法
2016/11/26 Javascript
inner join 内联与left join 左联的实例代码
2017/09/18 Javascript
EasyUI框架 使用Ajax提交注册信息的实现代码
2017/09/27 Javascript
深入理解ES6之数据解构的用法
2018/01/13 Javascript
JavaScript异步加载问题总结
2018/02/17 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
小程序实现悬浮搜索框
2019/07/12 Javascript
python实现TF-IDF算法解析
2018/01/02 Python
python 执行shell命令并将结果保存的实例
2018/05/11 Python
对python调用RPC接口的实例详解
2019/01/03 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
Django框架创建mysql连接与使用示例
2019/07/29 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
应届生财务会计求职信
2013/11/05 职场文书
楼面经理岗位职责范本
2014/02/18 职场文书
《闻一多先生的说和做》教学反思
2014/04/28 职场文书
股票投资建议书
2014/05/19 职场文书
拔河比赛口号
2014/06/10 职场文书
求职自我推荐信
2014/06/25 职场文书
商务英语专业求职信
2014/06/26 职场文书
清明节扫墓活动总结
2015/02/09 职场文书
会议通知
2015/04/15 职场文书
演讲开场白和结束语
2015/05/29 职场文书
预备党员表决心的话
2015/09/22 职场文书
三八红旗手先进事迹材料(2016推荐版)
2016/02/25 职场文书
教你用eclipse连接mysql数据库
2021/04/22 MySQL
oracle表分区的概念及操作
2021/04/24 Oracle
Win10 heic文件怎么打开 ? Win10 heic文件打开教程
2022/04/06 数码科技
Django框架中表单的用法
2022/06/10 Python