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 相关文章推荐
js 判断 enter 事件
Feb 12 Javascript
json 实例详细说明教程
Oct 31 Javascript
JQuery.Ajax之错误调试帮助信息介绍
Jul 04 Javascript
js onload事件不起作用示例分析
Oct 09 Javascript
js获取页面传来参数的方法
Sep 06 Javascript
JavaScript动态创建div等元素实例讲解
Jan 06 Javascript
JS验证逗号隔开可以是中文字母数字
Apr 22 Javascript
使用JavaScript实现ajax的实例代码
May 11 Javascript
JS实现页面跳转参数不丢失的方法
Nov 28 Javascript
jQuery中值得注意的trigger方法浅析
Dec 12 Javascript
Ajax和Comet技术总结
Feb 19 Javascript
echart简介_动力节点Java学院整理
Aug 11 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实现的下载远程图片自定义函数分享
2015/01/28 PHP
php使用cookie实现记住登录状态
2015/04/27 PHP
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
Jsonp 跨域的原理以及Jquery的解决方案
2010/05/18 Javascript
判断客户端浏览器是否安装了Flash插件的多种方法
2010/08/11 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
16个最流行的JavaScript框架[推荐]
2011/05/29 Javascript
jquery入门—数据删除与隔行变色以及图片预览
2013/01/07 Javascript
子窗体与父窗体传值示例js代码
2013/08/01 Javascript
js禁止页面复制功能禁用页面右键菜单示例代码
2013/08/29 Javascript
jQuery实现页面内锚点平滑跳转特效的方法总结
2015/05/11 Javascript
jQuery实现在列表的首行添加数据
2015/05/19 Javascript
浅析Bootstrap缩略图组件与警示框组件
2016/04/29 Javascript
原生JS实现首页进度加载动画
2016/09/14 Javascript
Vue.JS入门教程之自定义指令
2016/12/08 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
微信小程序tabBar模板用法实例分析【附demo源码下载】
2017/11/28 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
jQuery Dom元素操作技巧
2018/02/04 jQuery
vuejs实现折叠面板展开收缩动画效果
2018/09/06 Javascript
Javascript模块化机制实现原理详解
2020/04/02 Javascript
Nodejs环境实现socket通信过程解析
2020/07/03 NodeJs
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
使用Python为中秋节绘制一块美味的月饼
2019/09/11 Python
python通过nmap扫描在线设备并尝试AAA登录(实例代码)
2019/12/30 Python
Python中的Cookie模块如何使用
2020/06/04 Python
加拿大著名时装品牌:SOIA & KYO
2016/08/23 全球购物
EVE LOM英国官网:全世界最好的洁面膏
2017/10/30 全球购物
自我评价如何写好?
2014/01/05 职场文书
班长演讲稿范文
2014/04/24 职场文书
大学生交通专业求职信
2014/09/01 职场文书
2015年端午节活动总结
2015/02/11 职场文书
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
使用Python通过企业微信应用给企业成员发消息
2022/04/18 Python