Javascript中的常见排序算法


Posted in Javascript onMarch 27, 2007

具体代码及比较如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" lang="gb2312">  
<head>  
<title> 常见排序算法 之 JavaScript版 </title>  
<meta http-equiv="content-type" content="text/html; charset=gb2312" />  
<meta name="keywords" content="排序,算法,JavaScript排序" />  
<meta name="description" content="用JavaScript实现的常见排序算法:冒泡排序,选择排序,插入排序,谢尔排序,快速排序(递归),快速排序(堆栈),归并排序,堆排序" />  
<script type="text/javascript">  
 Array.prototype.swap = function(i, j)  
 {  
 var temp = this[i];  
 this[i] = this[j];  
 this[j] = temp;  
 }  
 Array.prototype.bubbleSort = function()  
 {  
 for (var i = this.length - 1; i > 0; --i)  
 {  
 for (var j = 0; j < i; ++j)  
 {  
 if (this[j] > this[j + 1]) this.swap(j, j + 1);  
 }  
 }  
 }  
 Array.prototype.selectionSort = function()  
 {  
 for (var i = 0; i < this.length; ++i)  
 {  
 var index = i;  
 for (var j = i + 1; j < this.length; ++j)  
 {  
 if (this[j] < this[index]) index = j;  
 }  
 this.swap(i, index);  
 }  
 }  
 Array.prototype.insertionSort = function()  
 {  
 for (var i = 1; i < this.length; ++i)  
 {  
 var j = i, value = this[i];  
 while (j > 0 && this[j - 1] > value)  
 {  
 this[j] = this[j - 1];  
 --j;  
 }  
 this[j] = value;  
 }  
 }  
 Array.prototype.shellSort = function()  
 {  
 for (var step = this.length >> 1; step > 0; step >>= 1)  
 {  
 for (var i = 0; i < step; ++i)  
 {  
 for (var j = i + step; j < this.length; j += step)  
 {  
 var k = j, value = this[j];  
 while (k >= step && this[k - step] > value)  
 {  
 this[k] = this[k - step];  
 k -= step;  
 }  
 this[k] = value;  
 }  
 }  
 }  
 }  
 Array.prototype.quickSort = function(s, e)  
 {  
 if (s == null) s = 0;  
 if (e == null) e = this.length - 1;  
 if (s >= e) return;  
 this.swap((s + e) >> 1, e);  
 var index = s - 1;  
 for (var i = s; i <= e; ++i)  
 {  
 if (this[i] <= this[e]) this.swap(i, ++index);  
 }  
 this.quickSort(s, index - 1);  
 this.quickSort(index + 1, e);  
 }  
 Array.prototype.stackQuickSort = function()  
 {  
 var stack = [0, this.length - 1];  
 while (stack.length > 0)  
 {  
 var e = stack.pop(), s = stack.pop();  
 if (s >= e) continue;  
 this.swap((s + e) >> 1, e);  
 var index = s - 1;  
 for (var i = s; i <= e; ++i)  
 {  
 if (this[i] <= this[e]) this.swap(i, ++index);  
 }  
 stack.push(s, index - 1, index + 1, e);  
 }  
 }  
 Array.prototype.mergeSort = function(s, e, b)  
 {  
 if (s == null) s = 0;  
 if (e == null) e = this.length - 1;  
 if (b == null) b = new Array(this.length);  
 if (s >= e) return;  
 var m = (s + e) >> 1;  
 this.mergeSort(s, m, b);  
 this.mergeSort(m + 1, e, b);  
 for (var i = s, j = s, k = m + 1; i <= e; ++i)  
 {  
 b[i] = this[(k > e || j <= m && this[j] < this[k]) ? j++ : k++];  
 }  
 for (var i = s; i <= e; ++i) this[i] = b[i];  
 }  
 Array.prototype.heapSort = function()  
 {  
 for (var i = 1; i < this.length; ++i)  
 {  
 for (var j = i, k = (j - 1) >> 1; k >= 0; j = k, k = (k - 1) >> 1)  
 {  
 if (this[k] >= this[j]) break;  
 this.swap(j, k);  
 }  
 }  
 for (var i = this.length - 1; i > 0; --i)  
 {  
 this.swap(0, i);  
 for (var j = 0, k = (j + 1) << 1; k <= i; j = k, k = (k + 1) << 1)  
 {  
 if (k == i || this[k] < this[k - 1]) --k;  
 if (this[k] <= this[j]) break;  
 this.swap(j, k);  
 }  
 }  
 }  
 function generate()  
 {  
 var max = parseInt(txtMax.value), count = parseInt(txtCount.value);  
 if (isNaN(max) || isNaN(count))  
 {  
 alert("个数和最大值必须是一个整数");  
 return;  
 }  
 var array = [];  
 for (var i = 0; i < count; ++i) array.push(Math.round(Math.random() * max));  
 txtInput.value = array.join("\n");  
 txtOutput.value = "";  
 }  
 function demo(type)  
 {  
 var array = txtInput.value == "" ? [] : txtInput.value.replace().split("\n");  
 for (var i = 0; i < array.length; ++i) array[i] = parseInt(array[i]);  
 var t1 = new Date();  
 eval("array." + type + "Sort()");  
 var t2 = new Date();  
 lblTime.innerText = t2.valueOf() - t1.valueOf();  
 txtOutput.value = array.join("\n");  
 }  
</script>  
</head>  
<body onload="generate();">  
<table style="font-size:12px;">  
<tr>  
 <td align="right">  
 <textarea id="txtInput" style="width:120px;height:500px;" readonly></textarea>  
 </td>  
 <td width="150" align="center">  
 随机数个数<input id="txtCount" value="500" style="width:50px" /><br /><br />  
 最大随机数<input id="txtMax" value="1000" style="width:50px" /><br /><br />  
 <button onclick="generate()">重新生成</button><br /><br /><br /><br />  
 耗时(毫秒):<label id="lblTime"></label><br /><br /><br /><br />  
 <button onclick="demo('bubble');">冒泡排序</button><br /><br />  
 <button onclick="demo('selection');">选择排序</button><br /><br />  
 <button onclick="demo('insertion');">插入排序</button><br /><br />  
 <button onclick="demo('shell');">谢尔排序</button><br /><br />  
 <button onclick="demo('quick');">快速排序(递归)</button><br /><br />  
 <button onclick="demo('stackQuick');">快速排序(堆栈)</button><br /><br />  
 <button onclick="demo('merge');">归并排序</button><br /><br />  
 <button onclick="demo('heap');">堆排序</button><br /><br />  
 </td>  
 <td align="left">  
 <textarea id="txtOutput" style="width:120px;height:500px;" readonly></textarea>  
 </td>  
</tr>  
</table>  
</body>  
</html> 

快速排序, 插入排序, 希尔排序, 冒泡排序, quickSort, insertSort, shellSort, bubbleSort, javascript排序
说明
写这个主要是为了锻炼自己,并无实际意义。
每个浏览器测试得出的数据会不一样。比如我用chrome 测试 一般快速排序都会最快,IE 则根据数组长度有可能希尔最快。
不要用太大数据去测试冒泡排序(浏览器崩溃了我不管)
如果有兴趣可以 下载测试页面

个人理解

冒泡排序:最简单,也最慢,貌似长度小于7最优
插入排序: 比冒泡快,比快速排序和希尔排序慢,较小数据有优势
快速排序:这是一个非常快的排序方式,V8的sort方法就使用快速排序和插入排序的结合
希尔排序:在非chrome下数组长度小于1000,希尔排序比快速更快
系统方法:在forfox下系统的这个方法非常快

算法源码

// ---------- 一些排序算法 
// js 利用sort进行排序 
systemSort:function(array){ 
return array.sort(function(a, b){ 
return a - b; 
}); 
}, 
// 冒泡排序 
bubbleSort:function(array){ 
var i = 0, len = array.length, 
j, d; 
for(; i<len; i++){ 
for(j=0; j<len; j++){ 
if(array[i] < array[j]){ 
d = array[j]; 
array[j] = array[i]; 
array[i] = d; 
} 
} 
} 
return array; 
}, 
// 快速排序 
quickSort:function(array){ 
//var array = [8,4,6,2,7,9,3,5,74,5]; 
//var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]; 
var i = 0; 
var j = array.length - 1; 
var Sort = function(i, j){ 
// 结束条件 
if(i == j ){ return }; 
var key = array[i]; 
var stepi = i; // 记录开始位置 
var stepj = j; // 记录结束位置 
while(j > i){ 
// j <<-------------- 向前查找 
if(array[j] >= key){ 
j--; 
}else{ 
array[i] = array[j] 
//i++ ------------>>向后查找 
while(j > ++i){ 
if(array[i] > key){ 
array[j] = array[i]; 
break; 
} 
} 
} 
} 
// 如果第一个取出的 key 是最小的数 
if(stepi == i){ 
Sort(++i, stepj); 
return ; 
} 
// 最后一个空位留给 key 
array[i] = key; 
// 递归 
Sort(stepi, i); 
Sort(j, stepj); 
} 
Sort(i, j); 
return array; 
}, 
// 插入排序 
insertSort:function(array){ 
// http://baike.baidu.com/image/d57e99942da24e5dd21b7080 
// http://baike.baidu.com/view/396887.htm 
//var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]; 
var i = 1, j, step, key, 
len = array.length; 
for(; i < len; i++){ 
step = j = i; 
key = array[j]; 
while(--j > -1){ 
if(array[j] > key){ 
array[j+1] = array[j]; 
}else{ 
break; 
} 
} 
array[j+1] = key; 
} 
return array; 
}, 
// 希尔排序 
//Jun.array.shellSort(Jun.array.df(10000)); 
shellSort:function(array){ 
// http://zh.wikipedia.org/zh/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F 
// var array = [13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10]; 
var stepArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1]; // reverse() 在维基上看到这个最优的步长 较小数组 
//var stepArr = [1031612713, 217378076, 45806244, 9651787, 2034035, 428481, 90358, 19001, 4025, 836, 182, 34, 9, 1]//针对大数组的步长选择 
var i = 0; 
var stepArrLength = stepArr.length; 
var len = array.length; 
var len2 = parseInt(len/2); 
for(;i < stepArrLength; i++){ 
if(stepArr[i] > len2){ 
continue; 
} 
stepSort(stepArr[i]); 
} 
// 排序一个步长 
function stepSort(step){ 
//console.log(step) 使用的步长统计 
var i = 0, j = 0, f, tem, key; 
var stepLen = len%step > 0 ? parseInt(len/step) + 1 : len/step; for(;i < step; i++){// 依次循环列 
for(j=1;/*j < stepLen && */step * j + i < len; j++){//依次循环每列的每行 
tem = f = step * j + i; 
key = array[f]; 
while((tem-=step) >= 0){// 依次向上查找 
if(array[tem] > key){ 
array[tem+step] = array[tem]; 
}else{ 
break; 
} 
} 
array[tem + step ] = key; 
} 
} 
} 
return array; 
}

测试代码打包下载
Javascript 相关文章推荐
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
Oct 20 Javascript
SOSO地图JS画出标注和中心点以html形式运行
Aug 09 Javascript
jQuery表格插件ParamQuery简单使用方法示例
Dec 05 Javascript
JQuery给网页更换皮肤的方法
May 30 Javascript
浅析JavaScript访问对象属性和方法及区别
Nov 16 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
Nov 25 Javascript
js实现数组内数据的上移和下移的实例
Nov 14 Javascript
基于vue展开收起动画的示例代码
Jul 05 Javascript
jQuery pjax 应用简单示例
Sep 20 jQuery
JavaScript显式数据类型转换详解
Mar 18 Javascript
vue导航栏部分的动态渲染实例
Nov 01 Javascript
原生js实现滑块区间组件
Jan 20 Javascript
一段多浏览器的&quot;复制到剪贴板&quot;javascript代码
Mar 27 #Javascript
CSDN轮换广告图片轮换效果
Mar 27 #Javascript
[原创]提供复制本站内容时出现,该文章转自脚本之家等字样的js代码
Mar 27 #Javascript
驱动事件的addEvent.js代码
Mar 27 #Javascript
网页自动刷新,不产生嗒嗒声的一个解决方法
Mar 27 #Javascript
统一接口:为FireFox添加IE的方法和属性的js代码
Mar 25 #Javascript
在Z-Blog中运行代码[html][/html](纯JS版)
Mar 25 #Javascript
You might like
PHP无限分类的类
2007/01/02 PHP
php中使用key,value,current,next和prev函数遍历数组的方法
2015/03/17 PHP
php中static 静态变量和普通变量的区别
2016/12/01 PHP
PHP解决中文乱码
2017/04/28 PHP
JavaScript快速检测浏览器对CSS3特性的支持情况
2012/09/26 Javascript
Extjs Gird 支持中文拼音排序实现代码
2013/04/15 Javascript
网页整体变灰白色(兼容各浏览器)实例
2013/04/21 Javascript
JQuery实现动态表格点击按钮表格增加一行
2014/08/24 Javascript
node.js中的path.sep方法使用说明
2014/12/08 Javascript
JQuery控制Radio选中方法分析
2015/05/29 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
JS生成不重复的随机数组的简单实例
2016/07/10 Javascript
js 获取本地文件及目录的方法(推荐)
2016/11/10 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
React中常见的动画实现的几种方式
2018/01/10 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
JavaScript中AOP的实现与应用
2019/05/06 Javascript
vuex实现购物车的增加减少移除
2020/06/28 Javascript
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
OpenCV实现人脸识别
2017/04/07 Python
Java编程迭代地删除文件夹及其下的所有文件实例
2018/02/10 Python
Python内存读写操作示例
2018/07/18 Python
浅谈Python 多进程默认不能共享全局变量的问题
2019/01/11 Python
Python使用os.listdir()和os.walk()获取文件路径与文件下所有目录的方法
2019/04/01 Python
python日志模块logbook使用方法
2019/09/19 Python
pip安装tensorflow的坑的解决
2020/04/19 Python
HTML5 标准将把互联网视频扔回到黑暗时代
2010/02/10 HTML / CSS
东芝官网商城:还原日式美学,打造美好生活
2018/12/27 全球购物
shell程序中如何注释
2012/02/17 面试题
Python面试题集
2012/03/08 面试题
推广普通话演讲稿
2014/05/23 职场文书
名人演讲稿范文
2014/09/16 职场文书
初中团委工作总结
2015/08/13 职场文书
2016先进工作者事迹材料
2016/02/25 职场文书
nginx作grpc的反向代理踩坑总结
2021/07/07 Servers
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python