冒泡,快排算法之javascript初体验
引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排。不用数组原生的 sort() 方法来实现冒泡和快排。
Part 1:冒泡排序(Bubble Sort)
- 原理:临近的两数两两进行比较,按从小到大或从大到小顺序排列,进行多趟,每一趟过去后(外循环),最大或最小的数字被交换到最后一位(内循环)。
- 代码:共进行6趟,每一趟比较5次
var a=[6,2,4,1,5,9],t;
for(var i=0;i<a.length;i++){
for(var j=0;j<a.length-1;j++){
if(a[j]>a[j+1]){
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
-----分割线----更正于2016.2.25
更正冒泡代码:
- 代码:共进行5趟(最后一趟即要开始比较的最后一个数不用比较了,它已经被其他趟挤到该在的位置了),每一趟比较5-i次,因为那i次在上一趟中已经排好序了在该在的位置了,肯定是前小后大没什么可比较的了,即后面继续比较无意义。
var a=[6,2,4,1,5,9],t;
for(var i=0;i<a.length-1;i++){
for(var j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
t=a[j];i
a[j]=a[j+1];
a[j+1]=t;
}
}
}
Part 2:快速排序(Quick Sort)
- 原理:在一个个数为n的序列中找一个数作为基准数(任意哪个皆可,一般找第一个),即找到该基准数所在位置k,k作为分界点,k左边数均小于基准数,k右边数均大于基准数。
- 具体做法:设置i,j两个指针分别指向最左端和最右端,每次比较都从j指针开始向左移动寻找比基准数小的数后停止移动,然后指针i向右移动寻找比基准数大的数后停止移动,交换此时i,j所指向的内容,这算一趟中的一次交换完成,直到i,j指针相遇位置即找到k,将基准数和k位置的数字交换,这算完成一趟排序。(解释一下为什么每次一定要从j指针移动开始:举个栗子说明,某序列为[3,1,2,5,4],基准数为3,i指向3,j指向4,如你所愿假设先从i移动找比3大的,i指针移动到5停止,j指针找比3小的,移动到5时相遇了,所以5的位置即为k,交换3和5,序列变为[5,1,2,3,4],这显然越排越乱。之所以一定要从右边开始就是保证了从右边过滤的是比基准数小的,然后再从左边移动时即使相遇了也能保证这个数比基准数小交换后不会影响序列)
- 分析原理:用分治的思想进行多趟寻找,每一趟都找出基准数所在位置,其中每一趟最坏情况都是两个指针指向了相邻元素,进行交换,这样比较次数和交换次数和冒泡一样了。所以快排在最坏情况下时间复杂度和冒泡一样O(n2)。但快排的平均时间复杂度为O(nlogn),快排之所以比冒泡有优势,在于每次交换都是跳跃式的,不一定每个位置都交换,而且每一趟序列的个数有可能是大于1那样的递减因为k位置不确定划分后才能确定左右两边序列个数,但冒泡每一趟比较序列的个数是规律的每次少一个(n,n-1,n-2...),快排不是像冒泡相邻交换,跳跃式的交换使交换距离变大,因此总的比较和交换次数变少,速度自然就提高。
- 举例:某序列[6,1,2,7,9,3, 4,5,10,8],说明以下图片均引用自网络(侵删)
以6作为基准数,寻找分界点k。
1.现在i,j指针均已就位

2.j指针先从右往左找小于6的数再停下,然后i指针再从左往右找大于6的数再停下,最后交换

3.第一趟的第一次交换完毕,序列变为[6,1,2,5,9,3,4,7,10,8]

4.j指针继续向左寻找小于6的元素,i指针继续向右寻找大于6的元素,最后交换

5.第一趟的第二次交换完毕,序列变为[6,1,2,5,4,3,9,7,10,8]

6.j指针继续向左寻找小于6的元素,i指针继续向右寻找大于6的元素,到3时相遇停止移动,即找到位置k

7.交换3和6,第一趟排序完毕。序列变为[3,1,2,5,4,6,9,7,10,8]


8.剩下的就每一趟都是按此方式重排,可用分治的思想解决,先解决6左边的序列,完毕后再解决6右边序列,直到不可拆分出新的子序列为止

- 代码:为了测试代码差点把浏览器搞崩,一不小心少了某个条件就进入死递归了。。。
function quicksort(a,left,right){
if(left>right){ //一定要有这个判断,因为有递归left和i-1,若没有这个判断条件,该函数会进入无限死错位递归
return;
} var i=left,
j=right,
jizhun=a[left]; //基准总是取序列开头的元素 while(i!=j){ //该while的功能为每一趟进行的多次比较和交换最终找到位置k。当i==j时意味着找到k位置了
while(a[j]>=jizhun&&i<j){j--} //只要大于等于基准数,j指针向左移动直到小于基准数才不进入该while。i<j的限制条件也是很重要,不然一直在i!=j这个循环里,j也会越界
while(a[i]<=jizhun&&i<j){i++} //只要小于等于基准数,i指针向右移动直到大于基准数才不进入该while。等于条件也是必要的,举例[4,7,6,4,3]验证一下是两个4交换
if(i<j){ //如果i==j跳出外层while
t=a[i];
a[i]=a[j];
a[j]=t
}
} a[left]=a[i];//交换基准数和k位置上的数
a[i]=jizhun; quicksort(a,left,i-1);
quicksort(a,i+1,right);
} var array=[4,7,2,8,3,9,12];
quicksort(array,0,array.length-1);//排完序后再看array是[2, 3, 4, 7, 8, 9, 12]
性能测试:在jsperf整了个链接测试一下冒泡,快排,sort()对100个数字排序的性能,http://jsperf.com/sortdemo 果然还是sort()原生方法快。
在chrome控制台统计代码执行的时间,也同样验证了sort()原生方法快:



参考:http://developer.51cto.com/art/201403/430986.htm
冒泡,快排算法之javascript初体验的更多相关文章
- 快排算法Java版-每次以最左边的值为基准值手写QuickSort
如题 手写一份快排算法. 注意, 两边双向找值的时候, 先从最右边起找严格小于基准值的值,再从最左边查找严格大于基准base的值; 并且先右后左的顺序不能反!!这个bug改了好久,233~ https ...
- 【算法】桶排->冒泡->快排
啊哈 算法 http://pan.baidu.com/s/1jGGl2SI http://pan.baidu.com/s/15C1oq 1 节 最快最简单的排序——桶排序 在我们生活的这个世界中到处都 ...
- Java写 插入 选择 冒泡 快排
/** * Created by wushuang on 2014/11/19. */ public class SortTest { @Test public void mainTest() { i ...
- python快排算法
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. ...
- 快排算法(C++版)
#include <iostream> using namespace std; /** Quick Sort * * split: cmp && swap * left ...
- oc 快排算法
直接复制粘贴就可以用了 - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *M_arr = [[NSMutableArray allo ...
- javascript初体验(一)
数据类型 数字 (Number),整数或浮点数,例如42或3.14159 字符串 (String) 布尔值 (Boolean) null (js大小写敏感,因此null和NULL不一样) undefi ...
- 快排 - 快速排序算法 (Chinar出品 简单易懂)
Quicksort 快排的简单讲解 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...
- scala写算法-快排
快排算法很经典,今天用scala的函数式思维来整理一下并实现: def qsort(list: List[Int]):List[Int]=list match { case Nil=>Nil c ...
随机推荐
- C# Redis分布式缓存
C# Redis实战(七) 七.修改数据 在上一篇 C# Redis实战(六)中介绍了如何查询Redis中数据,本篇将介绍如何修改Redis中相关数据.大家都知道Redis是key-value型存储系 ...
- HtmlWeb类
HtmlWeb类是一个从网络上获取一个HTML文档的类,其提供的功能大多是基于完成此需求出发.现在来来HtmlWeb类有哪些方法以及属性. 一.属性 bool AutoDetectEncoding { ...
- IOS实用功能之截图(来自相册和拍照)
// // ViewController.m // MyImagePicker1.0 // // Created by Mac on 14-7-14. // Copyright (c) 201 ...
- Web前段优化,提高加载速度 css
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个"Duang"的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒, ...
- Mosaic HDU 4819 二维线段树入门题
Mosaic Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- SQL 必知必会-- 第17课:创建和操作表
我这里用的是oracle 10g,PL/SQL来做的. 第17课 创建和操纵表 14517.1 创建表 14517.2 更新表 15017.3 删除表 15317.4 重命名表 1 ...
- 【阿里云产品公测】在Laravel4框架中使用阿里云OCS缓存
作者:阿里云用户 supechina Laravel 是我最近用得非常多而且越用就越喜欢的一款PHP框架,由于没有向下兼容的历史包袱,完全面向对象的风格,借助 Facades 优雅的 IoC Cont ...
- ASCII码表 char(9),char(10),char(13)等
char(9) 水平制表符 char(10) 换行 char(13) 回车 测试ASCII码的方法: 在记事本中,按住ALT键,同时用小键盘输入十进制的ASCII码,然后松手,就可以看到效果了! ...
- Hive编程(影印版)
<Hive编程(影印版)> 基本信息 原书名:Programming Hive 作者: Edward Capriolo Dean Wampler Jason Rutherglen 出版社: ...
- jquery.hichartTable.js插件绘图
使用场景:随日期不断增长变化的数据用折线图表现出来更加直观,比如注册人数的增长等. jquery.hichartTable.js文档:http://pmsipilot.github.io/jquery ...