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 用原型继承来实现对象系统
Mar 22 Javascript
js使用removeChild方法动态删除div元素
Aug 01 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
Aug 14 Javascript
JavaScript设计模式之单例模式实例
Sep 24 Javascript
express的中间件basicAuth详解
Dec 04 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
May 11 Javascript
Form表单上传文件(type=&quot;file&quot;)的使用
Aug 03 Javascript
使用svg实现动态时钟效果
Jul 17 Javascript
layer.open组件获取弹出层页面变量、函数的实例
Sep 25 Javascript
JS通用方法触发点击事件代码实例
Feb 17 Javascript
JS轮播图的实现方法
Aug 24 Javascript
Vue的生命周期一起来看看
Feb 24 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
php面向对象全攻略 (十五) 多态的应用
2009/09/30 PHP
PHP中的MYSQL常用函数(php下操作数据库必备)
2010/09/12 PHP
匹配csdn用户数据库与官方用户的重合度并将重叠部分的用户筛选出来
2011/12/25 PHP
Zend的Registry机制的使用说明
2013/05/02 PHP
PHP转换文件夹下所有文件编码的实现代码
2013/06/06 PHP
ThinkPHP模板判断输出Present标签用法详解
2014/06/30 PHP
php metaphone()函数及php localeconv() 函数实例解析
2016/05/15 PHP
CI框架文件上传类及图像处理类用法分析
2016/05/18 PHP
学习jquery必备 api中英文对照的chm手册 下载
2007/05/03 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
Prototype源码浅析 Enumerable部分之each方法
2012/01/16 Javascript
javascript学习笔记(七) js函数介绍
2012/06/19 Javascript
js对图片base64编码字符串进行解码并输出图像示例
2014/03/17 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
2016/07/01 Javascript
利用JQuery直接调用asp.net后台的简单方法
2016/10/27 Javascript
原生js实现旋转木马轮播图效果
2017/02/27 Javascript
webpack实现热加载自动刷新的方法
2017/07/30 Javascript
inquirer.js一个用户与命令行交互的工具详解
2019/05/18 Javascript
JavaScript中Dom操作实例详解
2019/07/08 Javascript
vuex管理状态仓库使用详解
2020/07/29 Javascript
[01:33]真香警告!DOTA2勇士令状不朽珍藏Ⅱ饰品欣赏
2018/06/26 DOTA
python多线程用法实例详解
2015/01/15 Python
python使用Flask框架获取用户IP地址的方法
2015/03/21 Python
Python Socket实现简单TCP Server/client功能示例
2017/08/05 Python
老生常谈Python startswith()函数与endswith函数
2017/09/08 Python
Numpy之文件存取的示例代码
2018/08/03 Python
windows系统中Python多版本与jupyter notebook使用虚拟环境的过程
2019/05/15 Python
Python标准库itertools的使用方法
2020/01/17 Python
python 爬虫如何实现百度翻译
2020/11/16 Python
python 装饰器重要在哪
2021/02/14 Python
沃尔玛加拿大:Walmart.ca
2020/03/02 全球购物
安全生产承诺书范文
2014/05/22 职场文书
口才训练演讲稿范文
2014/09/16 职场文书
搞笑Gif:这么白这么长的腿像极了一楼的女朋友
2022/03/21 杂记
volatile保证可见性及重排序方法
2022/08/05 Java/Android