一:你必须知道的

1> JS原型

2> 排序中的有序区和无序区

3> 二叉树的基本知识

如果你不知道上面三个东西,还是去复习一下吧,否则,看下面的东西有点吃力。

二:封装丑陋的原型方法

  1. Function.prototype.method = function(name, func){
  2. this.prototype[name] = func;
  3. return this;
  4. };

在下面的排序中都要用到这个方法。

三:9种排序算法的思路和实现

1> 插入排序

基本思路:

从无序区的第一个元素开始和它前面有序区的元素进行比较,如果比前面的元素小,那么前面的元素向后移动,否则就将此元素插入到相应的位置。

  1. Array.method('insertSort', function(){
  2. var len = this.length,
  3. i, j, tmp;
  4. for(i=1; i<len; i++){
  5. tmp = this[i];
  6. j = i - 1;
  7. while(j>=0 && tmp < this[j]){
  8. this[j+1] = this[j];
  9. j--;
  10. }
  11. this[j+1] = tmp;
  12. }
  13. return this;
  14. });

2> 二分插入排序

二分插入排序思路:

先在有序区通过二分查找的方法找到移动元素的起始位置,然后通过这个起始位置将后面所有的元素后移。

  1. Array.method('bInsertSort', function(){
  2. var len = this.length,
  3. i, j, tmp, low, high, mid;
  4. for(i=1; i<len; i++){
  5. tmp = this[i];
  6. low = 0;
  7. high = i - 1;
  8. while(low <= high){
  9. mid = (low+high)/2;
  10. if(tmp < this[mid]) high = mid - 1;
  11. else low = mid + 1;
  12. }
  13. for(j=i-1; j>=high+1; j--){
  14. this[j+1] = this[j];
  15. }
  16. this[j+1] = tmp;
  17. }
  18. return this;
  19. });

3> 希尔排序

希尔排序思路:

我们在第 i 次时取gap = n/(2的i次方),然后将数组分为gap组(从下标0开始,每相邻的gap个元素为一组),接下来我们对每一组进行直接插入排序。

  1. Array.method('shellSort', function(){
  2. var len = this.length, gap = parseInt(len/2),
  3. i, j, tmp;
  4. while(gap > 0){
  5. for(i=gap; i<len; i++){
  6. tmp = this[i];
  7. j = i - gap;
  8. while(j>=0 && tmp < this[j]){
  9. this[j+gap] = this[j];
  10. j = j - gap;
  11. }
  12. this[j + gap] = tmp;
  13. }
  14. gap = parseInt(gap/2);
  15. }
  16. return this;
  17. });

4> 冒泡排序

冒泡排序思想:

通过在无序区的相邻元素的比较和替换,使较小的元素浮到最上面。

  1. Array.method('bubbleSort', function(){
  2. var len = this.lenght,
  3. i, j, tmp;
  4. for(i=0; i<len; i++){
  5. for(j=len-1; j>i; j--){
  6. if(this[j] > this[j-1]){
  7. tmp = this[j-1];
  8. this[j-1] = this[j];
  9. this[j] = tmp;
  10. }
  11. }
  12. }
  13. return this;
  14. });

5> 改进的冒泡排序

基本思路:

如果在某次的排序中没有出现交换的情况,那么说明在无序的元素现在已经是有序了,就可以直接返回了。

  1. Array.method('rBubbleSort', function(){
  2. var len = this.length,
  3. i, j, tmp, exchange;
  4. for(i=0; i<len; i++){
  5. exchange = 0;
  6. for(j=len-1; j>i; j--){
  7. if(this[j] < this[j-1]){
  8. tmp = this[j];
  9. this[j] = this[j-1];
  10. this[j-1] = tmp;
  11. exchange = 1;
  12. }
  13. }
  14. if(!exchange) return this;
  15. }
  16. return this;
  17. });

6> 快速排序

快速排序思路:

1) 假设第一个元素为基准元素

2) 把所有比基准元素小的记录放置在前一部分,把所有比基准元素大的记录放置在后一部分,并把基准元素放在这两部分的中间(i=j的位置)

  1. Array.method('quickSort', function(s, t){
  2. var i=s, j=t,
  3. tmp;
  4. if(s < t){
  5. tmp = this[s];
  6. while(i!=j){
  7. while(j>i && this[j]>tmp) j--;//右—>左
  8. R[i] = R[j];
  9. while(i<j && this[j]<tmp) i++;//左—>右
  10. R[j] = R[i];
  11. }
  12. R[i] = tmp;
  13. this.quickSort(s, i-1);
  14. this.quickSort(i+1, t);
  15. }
  16. return this;
  17. });

7> 选择排序

选择排序思路:

在无序区中选出最小的元素,然后将它和无序区的第一个元素交换位置。

  1. Array.method('selectSort', function(){
  2. var len = this.length,
  3. i, j, k, tmp;
  4. for(i=0; i<len; i++){
  5. k = i;
  6. for(j=i+1; j<len; j++){
  7. if(this[j] < this[k]) k = j;
  8. }
  9. if(k!=i){
  10. tmp = this[k];
  11. this[k] = this[i];
  12. this[i] = tmp;
  13. }
  14. }
  15. return this;
  16. });

8> 堆排序

堆排序是一种树形选择排序方法(注意下标是从1开始的,也就是R[1...n])。

堆排序思路:

1) 初始堆:

将原始数组调整成大根堆的方法——筛选算法:

比较R[2i]、R[2i+1]和R[i],将最大者放在R[i]的位置上(递归调用此方法到结束)

2) 堆排序:

每次将堆顶元素与数组最后面的且没有被置换的元素互换。

  1. Array.method('createHeap', function(low, high){
  2. var i=low, j=2*i, tmp=this[i];
  3. while(j<=high){
  4. if(j< high && this[j]<this[j+1]) j++; //从左右子节点中选出较大的节点
  5. if(tmp < this[j]){ //根节点(tmp)<较大的节点
  6. this[i] = this[j];
  7. i = j;
  8. j = 2*i;
  9. }else break;
  10. }
  11. this[i] = tmp; //被筛选的元素放在最终的位置上
  12. return this;
  13. });
  14.  
  15. Array.method('heapSort', function(){
  16. var i, tmp, len=this.length-1;
  17. for(i=parseInt(len/2); i>=1; i--) this.createHeap(i, len);
  18. for(i=len; i>=2; i--){
  19. tmp = this[1];
  20. this[1] = this[i];
  21. this[i] = tmp;
  22. this.createHeap(1, i-1);
  23. }
  24. return this;
  25. });

9> 归并排序

归并排序思路:

1) 归并

从两个有序表R[low...mid]和R[mid+1...high],每次从左边依次取出一个数进行比较,将较小者放入tmp数组中,最后将两段中剩下的部分直接复制到tmp中。

这样tmp是一个有序表,再将它复制加R中。(其中要考虑最后一个子表的长度不足length的情况)

2) 排序

自底向上的归并,第一回:length=1;第二回:length=2*length ...

  1. Array.method('merge', function(low, mid, high){
  2. var tmp = new Array(), i = low, j=mid+1, k=0;
  3. while(i<=mid && j<=high){
  4. if(this[i] <= this[j]){//比较第一部分和第二部分,取较小者
  5. tmp[k] = this[i];
  6. i++;
  7. k++;
  8. }else{
  9. tmp[k] = this[j];
  10. j++;
  11. k++;
  12. }
  13. }
  14. while(i<=mid){
  15. tmp[k] = this[i];
  16. i++;
  17. k++;
  18. }
  19. while(j<=high){
  20. tmp[k] = this[j];
  21. j++;
  22. k++;
  23. }
  24. for(k=0,i=low; i<=high; k++,i++) this[i] = tmp[k];
  25.  
  26. return this;
  27. });
  28. Array.method('mergePass', function(length, n){
  29. var i;
  30. for(i=0; i+2*length-1<n; i=i+2*length) this.merge(i, i+length-1, i+2*length-1);
  31. if(i+length-1 < n) this.merge(i, i+length-1, n-1); //考虑到最后一个子表的长度可能小于length,所以要特殊处理一下
  32.  
  33. return this;
  34. });
  35.  
  36. Array.method('mergeSort', function(){
  37. var len = this.length,
  38. length;
  39. for(length=1; length<len; length=2*length) this.mergePass(length, len);
  40.  
  41. return this;
  42. });

四:测试

  1. var out = function(){
  2. console.log(arguments);
  3. }
  4. var test = [0,1,7,6,3,4,9,8];
  5. out(test.insertSort(), 'insertSort');
  6. var test = [0,1,7,6,3,4,9,8];
  7. out(test.bInsertSort(), 'bInsertSort');
  8. var test = [0,1,7,6,3,4,9,8];
  9. out(test.shellSort(), 'shellSort');
  10. var test = [0,1,7,6,3,4,9,8];
  11. out(test.bubbleSort(), 'bubbleSort');
  12. var test = [0,1,7,6,3,4,9,8];
  13. out(test.rBubbleSort(), 'rBubbleSort');
  14. var test = [0,1,7,6,3,4,9,8];
  15. out(test.quickSort(0, test.length-1), 'quickSort');
  16. var test = [0,1,7,6,3,4,9,8];
  17. out(test.selectSort(), 'selectSort');
  18. var test = [0,1,7,6,3,4,9,8];
  19. out(test.heapSort(), 'heapSort');
  20. var test = [0,1,7,6,3,4,9,8];
  21. out(test.mergeSort(), 'mergeSort');

秒杀9种排序算法(JavaScript版)的更多相关文章

  1. 排序算法JavaScript版

    冒泡排序 function bubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (va ...

  2. JavaScript实现的7种排序算法

    所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序.这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率.对于排序,我们首先要求 ...

  3. 十大排序算法JavaScript实现总结

    花费了几周的时间断断续续的练习和模仿与使用JavaScript代码实现了十大排序算法. 里面有每种算法的动图和静态图片演示,看到图片可以自己先按照图片的思路实现一下. github中正文链接,点击查看 ...

  4. 十大经典排序算法(Javascript实现)

    前言 总括: 本文结合动图详细讲述了十大经典排序算法用Javascript实现的过程. 原文博客地址:十大经典排序算法 公众号:「菜鸟学前端」,回复「666」,获取一揽子前端技术书籍 人生有情泪沾衣, ...

  5. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  6. PHP的几种排序算法的比较

    这里列出了几种PHP的排序算法的时间比较的结果,,希望对大家有所帮助 /* * php 四种排序算法的时间与内置的sort排序比较 * 3000个元素,四种算法的排序所用的时间比较 * 冒泡排序 85 ...

  7. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  8. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  9. 排序—时间复杂度为O(n2)的三种排序算法

    1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...

随机推荐

  1. Effective Java 33 Use EnumMap instead of ordinal indexing

    Wrong practice: Putting sets into an array indexed by the type's ordinal /** * Added demo for the &q ...

  2. keepalived+LVS搭建高可用负载均衡系统

    相关架构设置: 1)vip : 192.168.137.6 2)DS master ip : 192.168.137.8 3)DS backup ip : 192.168.137.9 4)RS 1 i ...

  3. 读书笔记——Windows环境下32位汇编语言程序设计(2)配置环境

    一直想买本罗云彬的Win32汇编书,现在终于出典藏版了,就买了本,读一读,涨涨姿势. 我把笔记本光驱拆下来添加了个硬盘,现在想装回去发现坏了,所以守着CD盘,代码却用的是第三版的,这真是个悲剧啊. - ...

  4. java使用httpcomponents 上传文件

    一.httpcomponents简介 httpcomponents 是apache下的用来负责创建和维护一个工具集的低水平Java组件集中在HTTP和相关协议的工程.我们可以用它在代码中直接发送htt ...

  5. cocos2d-x之value

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  6. Maven使用笔记,错误Failure to Transfer后处理

    当有未更新成功的项,M3会以后缀为.lastUpdated保存未更新成功的项 执行下面的操作可清楚这些项 Unixfind ~/.m2 -name "*.lastUpdated" ...

  7. Java语言中的基本词汇

    1.标识符包.类.方法.参数和变量的名称.大小写字母.数字._和$符号的组合,不以数字开始,不能使关键字,不能包括分隔符和换行.(严格区分大小写,最大长度255个字符) 2.字面量  某种类型的值(具 ...

  8. 该怎么快速完成ZBrush中脸部的雕刻

    骨骼,是一门基础艺术,几百年来一直为伟大的艺术大师所研究,它曾经,也将一直是创作现实且可信角色的关键,提高骨骼知识更将大大提高雕刻技能. 若有疑问可直接访问:http://www.zbrushcn.c ...

  9. c++仿函数 functor

    内容整理自国外C++教材 先考虑一个简单的例子:假设有一个vector<string>,你的任务是统计长度小于5的string的个数,如果使用count_if函数的话,你的代码可能长成这样 ...

  10. UIView.frame的骗局

    如果你刚刚开始接触IOS编程, 刚刚接触UIKit, 肯定会被 frame, bounds, center, layer.anchorPoint, layer.position 这些乱七八糟得属性折腾 ...