各种排序算法的对比总结如下表所示:

冒泡排序:

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
冒泡排序算法的运作如下:

比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,到最后一对比较完之后最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:C_{min}=n-1,M_{min}=0。

所以,冒泡排序最好的时间复杂度为O(n),冒泡排序的最坏时间复杂度为O(n^2)。综上,因此冒泡排序总的平均时间复杂度为O(n^2)。
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,
我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,
所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

function bubbleSort(arr) {
  var flag=false;  
for(var i=0;i<arr.length-1;i++){  
    for(var j=0;j<arr.length-1-i;j++){
      if(arr[j]>arr[j+1]){
        var temp=arr[j];
        arr[j]=arr[j+1];
        arr[j+1]=temp;
        flag=true;
      }
    }
    if(flag){
      flag=false;
    }else{
     break;
    }
  }
/* 输出结果 */
for (var k = 0; k < arr.length; k++) {
document.write(arr[k] + ",");
}
document.write("<br />");
/* 输出结果结束 */ }

选择排序:

每一趟从待排序的数据元素中选出最小(或最大)的一个元素,然后和最小或者最大的位置的元素交换位置,直到所有元素排完。 选择排序是不稳定的排序方法。
初始关键字 [49 38 65 97 76 13 27 49]
第一趟排序后 13 [38 65 97 76 49 27 49]
第二趟排序后 13 27 [65 97 76 49 38 49]
第三趟排序后 13 27 38 [97 76 49 65 49]
第四趟排序后 13 27 38 49 [76 97 65 49 ]
第五趟排序后 13 27 38 49 49 [97 65 76]
第六趟排序后 13 27 38 49 49 65 [97 76]
第七趟排序后 13 27 38 49 49 65 76 [97]
最后排序结果 13 27 38 49 49 65 76 97
选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。
比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;
最坏情况是,逆序,交换n-1次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

 function selectSort(array) {
var min, temp; ;
for (var i = 0; i < array.length; i++) {
min = i;
for (var j = i + 1; j < array.length; j++) {
if (array[min] > array[j])
min = j;
}
if (min != i) {
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
/* 输出结果 */
document.write("第 + i + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
} document.write("<br />")
/* 输出结果结束 */ }
}

直接插入排序:

每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1)。
function insertSort(array) {
var temp;
for (var i = 1; i < array.length; i++) {
var temp = array[i];
for (var j = i; j > 0; j--) {
if(temp < array[j - 1]){
array[j] = array[j - 1];
}
}
array[j] = temp;
document.write("第?" + i + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
} document.write("<br />");
}
}

快速排序:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

值得注意的是,快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

        var count = 0;
function quickSort(array, low, high) {
var temp;
if (low < high) {
var keypoint = QuickSortHelp(array, low, high);
count++;
document.write("<br />第" + count + "遍排序的结果是:")
for (var l = 0; l < array.length; l++) {
document.write(array[l] + ",");
}
quickSort(array, low, keypoint - 1);
quickSort(array, keypoint + 1, high);
}
}
function QuickSortHelp(array, low, high) {
while (low < high) {
while (low < high && array[low] <= array[high]) {
high--;
}
temp = array[low];
array[low] = array[high];
array[high] = temp;
while (low < high && array[low] <= array[high]) {
low++
}
temp = array[low];
array[low] = array[high];
array[high] = temp;
}
return low;
}

堆排序:

堆的定义:n个关键字序列Kl,K2,…,Kn称为(Heap),当且仅当该序列满足如下性质(简称为堆性质):

(1)ki<=k(2i)且ki<=k(2i+1)(1≤i≤ n),当然,这是小根堆,大根堆则换成>=号。//k(i)相当于二叉树的非叶子节点,K(2i)则是左子节点,k(2i+1)是右子节点。
大根堆排序算法的基本操作:

① 初始化操作:将R[1..n]构造为初始堆;
② 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。
function heapSort(array) {
var temp;
var i;
for (i = Math.floor(array.length / 2); i >= 0; i--) {
heapAdjust(array, i, array.length - 1); //将数组array构建成一个大顶堆
}
for (i = array.length - 1; i >= 0; i--) {
/*把根节点交换出去*/
temp = array[i];
array[i] = array[0];
array[0] = temp;
/*余下的数组继续构建成大顶堆*/
heapAdjust(array, 0, i - 1);
/* 输出结果 */
document.write("<br />第 + (array.length - i).toString() + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
}
/* 输出结果结束 */
}
}
//要调整的子树
//start为数组开始下标
//max是数组结束下标
function heapAdjust(array, start, max) {
var temp, j;
temp = array[start];//temp是根节点的值
for (j = 2 * start; j < max; j *= 2) {
if (j < max && array[j] < array[j + 1]) { //取得较大孩子的下标
++j;
}
if (temp >= array[j])
break;
array[start] = array[j];
start = j;
}
array[start] = temp;
}

希尔排序:

希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

 function shallSort(array) {
var increment = array.length;
var i
var temp; //暂存
var count = 0;
do {
increment = Math.floor(increment / 3) + 1;
for (i = increment; i < array.length; i++) {
if (array[i] < array[i - increment]) {
temp = array[i];
for (var j = i - increment; j > 0 && temp < array[j]; j -= increment) { array[j + increment] = array[j]; }
array[j + increment] = temp;
/* 输出结果 */
count++;
document.write("<br />第 + count + "遍排序的结果是:")
for (var n = 0; n < array.length; n++) {
document.write(array[n] + ",");
}
/* 输出结果结束 */
}
}
}
while (increment > 1) }

归并排序:

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
值得注意的是归并排序是一种稳定的排序方法。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序,称为2-路归并
归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
如 设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数(逆序数)为:3+4+4=11;
        //source源数组

        //dest目标数组
//s起始下标
//t目标下标
function mSort(source, dest, s, t) {
var m; //取中间值
var dest2 = new Array();
if (s == t) {
dest[s] = source[s]; }
else {
m = Math.floor((s + t) / 2);
mSort(source, dest2, s, m);
mSort(source, dest2, m+1 , t);
merge(dest2, dest, s, m, t);
/* 输出结果 */
document.write("<br />第 + ++count + "遍排序的结果是:")
for (var n = 0; n < dest.length; n++) {
document.write(array[n] + ",");
}
/* 输出结果结束 */
} } //将两个数组按照从小到大的顺序融合
//source原数组
//dest排序后的数组
//s第一个下标
//m第二个数组下标
//总长度
function merge(source, dest, s, m, n) {
for (var j = m+1, k = s; j <= n && s <= m; k++) {
if (source[s] < source[j]) {
dest[k] = source[s++];
}
else {
dest[k] = source[j++];
}
} //将剩余排不完的有序数组加入到dest的末端
if (s <= m) {
for (var l = 0; l <= m - s; l++) {
dest[k + l] = source[s+l];
}
}
if (j <= n) {
for (var l = 0; l <= n - j; l++) {
dest[k + l] = source[j+l];
} }
}

各种排序方法的JS实现的更多相关文章

  1. jquery自带的排序方法(js也是)

    jquery.sort()   js.sort() <!DOCTYPE html> <html>   <head>     <meta charset=&qu ...

  2. JS学习笔记(3)--json格式数据的添加,删除及排序方法

    这篇文章主要介绍了json格式数据的添加,删除及排序方法,结合实例形式分析了针对一维数组与二维数组的json格式数据进行增加.删除与排序的实现技巧,需要的朋友可以参考下   本文实例讲述了json格式 ...

  3. js 几种排序方法

    1.冒泡排序 var arr = [9, 7, 5, 3, 1]; for (var i = 0; i < arr.length - 1; i++) { for (var j = 0; j &l ...

  4. js字符串排序方法

    前端开发过程中有时需自己手写排序方法 一般想到数字的字符串排序方法 我们会用到 var newArr = arr. sort(function(a,b){return a - b})来进行排序 但除此 ...

  5. 拖放排序插件Sortable.js 兼容好及功能全个人觉得比dragula.js 好的多

    经测试,Sortable.js 兼容好和使用方便都是比较不错的,特别手机端使用很棒 介绍 Sortable.js是一款轻量级的拖放排序列表的js插件(虽然体积小,但是功能很强大)下载地址:https: ...

  6. JavaScript高级程序设计--对象,数组(栈方法,队列方法,重排序方法,迭代方法)

    1.使用对象字面量定义对象 var person={}; 使用这种方式创建对象时,实际上不会调用Object构造函数. 开发人员更喜欢对象字面量的语法.   2.有时候需要传递大量可选参数的情形时,一 ...

  7. php语言实现的7种基本的排序方法

    今天总结了一下常用的7种排序方法,并用php语言实现. 直接插入排序 /* * 直接插入排序,插入排序的思想是:当前插入位置之前的元素有序, * 若插入当前位置的元素比有序元素最后一个元素大,则什么也 ...

  8. C语言中常见的排序方法

    在C语言中,常见的排序方法有冒泡法,排序法,插入法等等.所谓的冒泡法,就是对一组数字进行从大到小或者从小到大的一种排序方法.主要就是相邻的数值相互交换.从第一个数值开始,如果这相邻的两个数值排序与我们 ...

  9. Atitit.现实生活中最好使用的排序方法-----ati排序法总结

    Atitit.现实生活中最好使用的排序方法-----ati排序法总结 1. 现在的问题 1 2. 排序的类别::插入排序//交换排序//选择排序(每次最小/大排在相应的位置  )//归并排序//基数排 ...

随机推荐

  1. sql事务,在sql2000里判断执行是否成功用@@ERROR 判断

    原文:sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 贴个sql事务,在sql2000里判断执行是否成功用@@ERROR 判断 这个东西多少还是有点问题,sql2005了可以用t ...

  2. CSharp设计模式读书笔记(15):命令模式(学习难度:★★★☆☆,使用频率:★★★★☆)

    命令模式(Command Pattern):将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.命令模式是一种对象行为型模式,其别名为 ...

  3. 【百度地图API】今日小年大进步,齐头共进贺佳节——API优化升级上线,不再增加内存消耗

    原文:[百度地图API]今日小年大进步,齐头共进贺佳节--API优化升级上线,不再增加内存消耗 任务描述: 今天是2011年01月26日,小年夜.百度地图API在小年夜献给广大API爱好者一份给力的礼 ...

  4. 安装ruby on rail

    安装: # nvm 安装, 两种方法 $ curl https://raw.githubusercontent.com/creationix/nvm/v0.8.0/install.sh | sh $ ...

  5. Android基础之——startActivityForResult启动界面并返回数据,上传头像

    在android应用的开发过程中,常常会出现启动一个界面后填写部分内容后带着数据返回启动前的界面,最典型的应用就是登录过程.在非常多应用程序的模块中,都有"我的"这个模块,在未登录 ...

  6. AForge.NET 工具源码下载

    AForge.NET是一个专门为开发者和研究者基于C#框架设计的,这个框架提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,机器 ...

  7. RESTful API的设计原则

    好RESTful API的设计原则   说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间, ...

  8. Java获取系统相关信息System.getProperty()

    java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目 ...

  9. Windows,查看进程的连接的IP地址,批量模式,最后做成Excel

    1.CMD -> netstat -ano,复制到UltraEdit 2.把双空格替换为单空格,这种替换要进行很多次,直到全部替换完.其次点20次替换就行了. 3.单空格替换为 ^t,也就是制表 ...

  10. 分布式消息系统kafka

    kafka:一个分布式消息系统 1.背景 最近因为工作需要,调研了追求高吞吐的轻量级消息系统Kafka,打算替换掉线上运行的ActiveMQ,主要是因为明年的预算日流量有十亿,而ActiveMQ的分布 ...