JavaScript中的排序算法代码


Posted in Javascript onFebruary 22, 2011

作为排序依据的数据项称为“排序码”,也即数据元素的关键码。为了便于查找,通常希望计算机中的数据表是按关键码有序的。如有序表的折半查找,查找效率较高。还有,二叉排序树、B-树和B+树的构造过程就是一个排序过程。若关键码是主关键码,则对于任意待排序序列,经排序后得到的结果是唯一的;若关键码是次关键码,排序结果可能不唯一,这是因为具有相同关键码的数据元素,这些元素在排序结果中,它们之间的的位置关系与排序前不能保持。
若对任意的数据元素序列,使用某个排序方法,对它按关键码进行排序:若相同关键码元素间的位置关系,排序前与排序后保持一致,称此排序方法是稳定的;而不能保持一致的排序方法则称为不稳定的。
排序分为两类:内排序和外排序。
内排序:指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。
外排序:指排序过程中还需访问外存储器,足够大的元素序列,因不能完全放入内存,只能使用外排序。

现在贴3种排序算法的JavaScript实现。

首先是最简单的,是个人都会的冒泡排序。就不多说了,直接贴代码

/** @name 冒泡排序 
* @lastmodify 2010/07/13 
* @desc 比较排序 
复杂度为O(n*n) 
*/ 
function BubbleSort(list){ 
var len = list.length; 
var cl,temp; 
while(len--){ 
cl = list.length; 
while(cl--){ 
if(list[cl]>list[len] && cl < len){ 
temp = list[len]; 
list[len] = list[cl]; 
list[cl] = temp; 
} 
} 
} 
return list; 
}

然后是最常见的快速排序,面试基本上都会问到。
/** @name 快速排序 
* @lastmodify 2010/07/14 
* @desc 比较排序 
最差运行时间O(n*n); 
最好运行时间O(nlogn) 
*/ 
function QuickSort(list){ 
var i = 0; 
var j = list.length; 
var len = j; 
var left; 
var right; 
var k = findK(i , j); 
if(k != 0){ 
var leftArr = []; 
var rightArr = []; 
var midArr = [list[k]]; 
while(len--) { 
if(len != k){ 
if(list[len] > list[k]){ 
rightArr.push(list[len]); 
} 
else{ 
leftArr.push(list[len]); 
} 
} 
} 
left = QuickSort(leftArr); 
right = QuickSort(rightArr); 
list = left.concat(midArr).concat(right); 
} 
return list; 
} function findK(i,j){ 
//默认找它的中间位置 
return Math.floor((i + j) / 2); 
}

快速排序的主要思想就是分治法,将被排序的序列分割为2块,从而将排序的复杂度降低。递归的巧用也是快速排序的精妙之处。在上个例子中,首先使用findK函数找出“参照元素”,其他元素依次和该元素进行比较,所有比其大的放入一个集合中,比其小的放入另外一个集合中,再分别对两个集合进行排序。快速排序的效率主要取决于findK函数的实现和待排序元素的有序程度。因此,快速排序是一个不稳定的排序算法。

但是快速排序仍然是一个基于比较的排序算法。所有基于比较的排序算法有一个特点,就是无论怎样优化,它对于一个元素集合的平均排序时间总是随着该集合元素数量的增加而增加。而非比较的排序很好的克服了这个缺点,它们试图让排序时间复杂度趋于一个数量无关的稳定值。其中比较有代表性的就是桶排序了。先看看它的JavaScript实现。

/** @name 桶排序 
* @author lebron 
* @lastmodify 2010/07/15 
* @desc 非比较排序 
*/ 
function BucketSort(list) { 
var len = list.length; 
var range = findMax(list); 
var result = [], 
count = []; 
var i,j; 
for (i = 0; i < range; i++) { 
count.push(0); 
} for ( j = 0; j < len; j++) { 
count[list[j]]++; 
result.push(0); 
} 
for (i = 1; i < range; i++) { 
count[i] = count[i-1] + count[i]; 
} 
for (j = len - 1; j >= 0; j--) { 
result[count[list[j]]] = list[j]; 
count[list[j]]--; 
} 
return result; 
} 
function findMax(list) { 
return MAX; 
}

可以看到,在桶排序的实现中,仍然使用了一个findMax函数来确定一个大数组的范围,这里直接用一个常量MAX来代替。首先初始化一个大数组count,长度为MAX。在将被排序集合里面的值放入到对应的位置上去,比如有一个元素值为24,那么count的第24位被标记为1,同时result数组长度+1。再计算出count数组中标志为1的元素位置在整个count数组中标志为1的排位。此时count数组中,第n个元素的值,就应当是排序后它的位置,而n这是这个排序后这个位置对应的值。所以,最后再一一的将count数组里面的键值倒过来映射入结果数组中即可。
桶排序巧妙的利用了这样一种思想,如果一个元素它在一个集合中是第n大的,那么它应该排第n位,而无需关心它前一位或者后一位是比它大还是比它小(无需比较)。很显然的是,在实际情况中,被排序集合的元素的值的范围很可能远远大于这个集合的元素数量,因此,也需要分配相应的一个巨大空间的数组才行。因此,桶排序的常见场景是在外排序上面。

有兴趣的同学,可以测试下3种排序在不同数量级下的耗时。

Javascript 相关文章推荐
javascript 正则表达式相关应介绍
Nov 27 Javascript
使用jQuery.fn自定义jQuery翻页插件
Jan 20 Javascript
jQuery获得内容和属性示例代码
Jan 16 Javascript
利用Javascript实现BMI计算器
Aug 16 Javascript
原生JS简单实现ajax的方法示例
Nov 29 Javascript
基于webpack-hot-middleware热加载相关错误的解决方法
Feb 22 Javascript
详解使用create-react-app添加css modules、sasss和antd
Jul 31 Javascript
vue服务端渲染缓存应用详解
Sep 12 Javascript
vue实现输入一位数字转汉字功能
Dec 13 Javascript
js实现移动端吸顶效果
Jan 08 Javascript
ckeditor一键排版功能实现方法分析
Feb 06 Javascript
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
JavaScript中几种常见排序算法小结
Feb 22 #Javascript
用JS控制回车事件的代码
Feb 20 #Javascript
apycom出品的jQuery精美菜单破解方法
Feb 18 #Javascript
自制基于jQuery的智能提示插件一枚
Feb 18 #Javascript
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
Feb 18 #Javascript
js判断IE6/IE7/FF的代码[XMLHttpRequest]
Feb 16 #Javascript
基于jquery的复制网页内容到WORD的实现代码
Feb 16 #Javascript
You might like
ThinkPHP实现将本地文件打包成zip下载
2014/06/26 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
jquery 学习之二 属性相关
2010/11/23 Javascript
dwz 如何去掉ajaxloading具体代码
2013/05/22 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
JS实现5秒钟自动封锁div层的方法
2015/02/20 Javascript
tuzhu_req.js 实现仿百度图片首页效果
2015/08/11 Javascript
iframe跨域通信封装详解
2015/08/11 Javascript
jQuery地图map悬停显示省市代码分享
2015/08/20 Javascript
JS实现黑色风格的网页TAB选项卡效果代码
2015/10/09 Javascript
基于jquery实现轮播焦点图插件
2016/03/31 Javascript
jQuery中DOM节点的删除方法总结(超全面)
2017/01/22 Javascript
Angualrjs和bootstrap相结合实现数据表格table
2017/03/30 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
jsonp跨域获取百度联想词的方法分析
2019/05/13 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
Python的Bottle框架中获取制定cookie的教程
2015/04/24 Python
快速了解Python开发中的cookie及简单代码示例
2018/01/17 Python
django ajax json的实例代码
2018/05/29 Python
Django实现WebSSH操作物理机或虚拟机的方法
2019/11/06 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
HTTP状态码详解
2021/03/18 杂记
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
HTML5 预加载让页面得以快速呈现
2013/08/13 HTML / CSS
国外平面设计第一市场:99designs
2016/10/25 全球购物
澳大利亚宠物商店:Petbarn
2017/11/18 全球购物
计算机通信工程专业毕业生推荐信
2013/12/24 职场文书
全民健身日活动方案
2014/01/29 职场文书
十八届三中全会报告学习材料
2014/02/17 职场文书
大学生标准自荐书
2014/06/15 职场文书
中秋节活动总结
2014/08/29 职场文书
财产分割协议书
2016/03/22 职场文书
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL
《王者天下》第4季首话新剧照 4月9日正式开播
2022/04/07 日漫
vscode内网访问服务器的方法
2022/06/28 Servers