File tree Expand file tree Collapse file tree 9 files changed +141
-29
lines changed Expand file tree Collapse file tree 9 files changed +141
-29
lines changed Original file line number Diff line number Diff line change 1
1
# 冒泡排序
2
2
3
+ 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
4
+
3
5
作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来说并没有什么太大作用。
4
6
5
7
6
- ## 1. 什么时候最快
8
+ ## 1. 算法步骤
7
9
8
- 当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊) 。
10
+ 1 . 比较相邻的元素。如果第一个比第二个大,就交换他们两个 。
9
11
12
+ 2 . 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
10
13
11
- ## 2. 什么时候最慢
14
+ 3 . 针对所有的元素重复以上的步骤,除了最后一个。
12
15
13
- 当输入的数据是反序时(写一个for循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗) 。
16
+ 4 . 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较 。
14
17
15
18
16
- ## 3 . 动图演示
19
+ ## 2 . 动图演示
17
20
18
21
![ 动图演示] ( res/bubbleSort.gif )
19
22
20
23
21
- ## 4. JavaScript 代码实现
24
+ ## 3. 什么时候最快
25
+
26
+ 当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊)。
27
+
28
+
29
+ ## 4. 什么时候最慢
30
+
31
+ 当输入的数据是反序时(写一个for循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。
32
+
33
+
34
+ ## 5. JavaScript 代码实现
22
35
23
36
``` js
24
37
function bubbleSort (arr ) {
Original file line number Diff line number Diff line change 1
1
# 基数排序
2
2
3
- 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来说并没有什么太大作用 。
3
+ 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数 。
4
4
5
5
6
6
## 1. 基数排序 vs 计数排序 vs 桶排序
Original file line number Diff line number Diff line change 1
1
# 选择排序
2
2
3
- 表现最稳定的排序算法之一 ,因为无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
3
+ 选择排序是一种简单直观的排序算法,是表现最稳定的排序算法之一 ,因为无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
4
4
5
5
6
- ## 1. 动图演示
6
+ ## 1. 算法步骤
7
+
8
+ 1 . 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
9
+
10
+ 2 . 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
11
+
12
+ 3 . 重复第二步,直到所有元素均排序完毕。
13
+
14
+
15
+ ## 2. 动图演示
7
16
8
17
![ 动图演示] ( res/selectionSort.gif )
9
18
10
19
11
- ## 2 . JavaScript 代码实现
20
+ ## 3 . JavaScript 代码实现
12
21
13
22
``` js
14
23
function selectionSort (arr ) {
Original file line number Diff line number Diff line change 1
1
# 插入排序
2
2
3
- 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。当然,如果你说你打扑克牌摸牌的时候从来不按牌的大小整理牌,那估计这辈子你对插入排序的算法都不会产生任何兴趣了 。
3
+ 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入 。
4
4
5
- 插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。对于这种算法,得了懒癌的我就套用教科书上的一句经典的话吧:感兴趣的同学可以在课后自行研究。
5
+ 插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
6
6
7
7
8
- ## 1. 动图演示
8
+ ## 1. 算法步骤
9
+
10
+ 1 . 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
11
+
12
+ 2 . 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
13
+
14
+
15
+ ## 2. 动图演示
9
16
10
17
![ 动图演示] ( res/insertionSort.gif )
11
18
12
19
13
- ## 2 . JavaScript 代码实现
20
+ ## 3 . JavaScript 代码实现
14
21
15
22
``` js
16
23
function insertionSort (arr ) {
Original file line number Diff line number Diff line change 1
1
# 希尔排序
2
2
3
- 希尔排序是插入排序的一种更高效率的实现。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第4版》的合著者 Robert Sedgewick 提出的。在这里,我就使用了这种方法 。
3
+ 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法 。
4
4
5
+ 希尔排序是基于插入排序的以下两点性质而提出改进方法的:
5
6
6
- ## 1. JavaScript 代码实现
7
+ - 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
8
+ - 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
9
+
10
+ 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
11
+
12
+
13
+ ## 1. 算法步骤
14
+
15
+ 1 . 选择一个增量序列t1,t2,…,tk,其中 ti > tj,tk=1;
16
+
17
+ 2 . 按增量序列个数 k,对序列进行 k 趟排序;
18
+
19
+ 3 . 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
20
+
21
+
22
+ ## 2. JavaScript 代码实现
7
23
8
24
``` js
9
25
function shellSort (arr ) {
Original file line number Diff line number Diff line change 1
1
# 归并排序
2
2
3
+ 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
4
+
3
5
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
4
6
- 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第2种方法);
5
7
- 自下而上的迭代;
6
8
7
9
在《数据结构与算法JavaScript描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为:
8
10
9
-
10
11
> However, it is not possible to do so in JavaScript, as the recursion goes too deep for the language to handle.
11
12
>
12
13
> 然而,在 JavaScript 中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。
17
18
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。
18
19
19
20
20
- ## 1. 动图演示
21
+ ## 2. 算法步骤
22
+
23
+ 1 . 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
24
+
25
+ 2 . 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
26
+
27
+ 3 . 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
28
+
29
+ 4 . 重复步骤3直到某一指针达到序列尾;
30
+
31
+ 5 . 将另一序列剩下的所有元素直接复制到合并序列尾。
32
+
33
+
34
+ ## 3. 动图演示
21
35
22
36
![ 动图演示] ( res/mergeSort.gif )
23
37
24
38
25
- ## 2 . JavaScript 代码实现
39
+ ## 4 . JavaScript 代码实现
26
40
27
41
``` js
28
42
function mergeSort (arr ) { // 采用自上而下的递归方法
Original file line number Diff line number Diff line change 1
1
# 快速排序
2
2
3
+ 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
4
+
5
+ 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
6
+
3
7
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
4
8
5
9
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高! 它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了N多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
6
10
7
11
> 快速排序的最坏运行情况是O(n²),比如说顺序数列的快排。但它的平摊期望时间是O(n log n) ,且O(n log n)记号中隐含的常数因子很小,比复杂度稳定等于O(n log n)的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
8
12
9
13
10
- ## 1. 动图演示
14
+ ## 1. 算法步骤
15
+
16
+ 1 . 从数列中挑出一个元素,称为 “基准”(pivot);
17
+
18
+ 2 . 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
19
+
20
+ 3 . 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
21
+
22
+ 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
23
+
24
+
25
+ ## 2. 动图演示
11
26
12
27
![ 动图演示] ( res/quickSort.gif )
13
28
14
29
15
- ## 2 . JavaScript 代码实现
30
+ ## 3 . JavaScript 代码实现
16
31
17
32
``` js
18
33
function quickSort (arr , left , right ) {
Original file line number Diff line number Diff line change 1
1
# 堆排序
2
2
3
- 堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
3
+ 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
4
4
5
5
1 . 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
6
6
2 . 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
7
7
8
+ 堆排序的平均时间复杂度为Ο(nlogn) 。
8
9
9
- ## 1. 动图演示
10
+
11
+ ## 1. 算法步骤
12
+
13
+ 1 . 创建一个堆 H[ 0..n-1] ;
14
+
15
+ 2 . 把堆首(最大值)和堆尾互换;
16
+
17
+ 3 . 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
18
+
19
+ 4 . 重复步骤 2,直到堆的尺寸为 1。
20
+
21
+
22
+ ## 2. 动图演示
10
23
11
24
![ 动图演示] ( res/heapSort.gif )
12
25
13
26
14
- ## 2 . JavaScript 代码实现
27
+ ## 3 . JavaScript 代码实现
15
28
16
29
``` js
17
30
var len; // 因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
Original file line number Diff line number Diff line change 1
1
# 十大经典排序算法
2
2
3
- 排序算法是《数据结构与算法》中最基本的算法之一。用一张图概括:
3
+ 排序算法是《数据结构与算法》中最基本的算法之一。
4
+
5
+ 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:** 插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序** 等。用一张图概括:
4
6
5
7
![ 十大经典排序算法 概览截图] ( res/sort.png )
6
8
7
9
8
- 名词解释:
10
+ ** 关于时间复杂度** :
11
+
12
+ 1 . 平方阶 (O(n2)) 排序
13
+ 各类简单排序:直接插入、直接选择和冒泡排序。
14
+ 2 . 线性对数阶 (O(nlog2n)) 排序
15
+ 快速排序、堆排序和归并排序;
16
+ 3 . O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。
17
+ 希尔排序
18
+ 4 . 线性阶 (O(n)) 排序
19
+ 基数排序,此外还有桶、箱排序。
20
+
21
+
22
+ ** 关于稳定性** :
23
+
24
+ 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。
25
+
26
+ 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。
27
+
28
+
29
+ ** 名词解释** :
9
30
10
31
** n** :数据规模
11
32
20
41
----
21
42
22
43
23
- ** GitHook 内容大纲**
44
+ ** GitBook 内容大纲**
24
45
25
46
1 . [ 冒泡排序] ( 1.bubbleSort.md )
26
47
2 . [ 选择排序] ( 2.selectionSort.md )
35
56
36
57
----
37
58
38
- 为了方便大家学习排序算法,整理文章内容成 GitBook:[ https://wowphp.com/post/komxdx8qe862.html ] ( https://wowphp.com/post/komxdx8qe862.html )
59
+ 本书内容来源于:
60
+ - [ https://wowphp.com/post/komxdx8qe862.html ] ( https://wowphp.com/post/komxdx8qe862.html )
61
+ - [ http://www.jcodecraeer.com/a/chengxusheji/shejimoshi/2015/0527/2941.html ] ( http://www.jcodecraeer.com/a/chengxusheji/shejimoshi/2015/0527/2941.html )
62
+
63
+ 开源项目地址:[ https://github.com/hustcc/JS-Sorting-Algorithm ] ( https://github.com/hustcc/JS-Sorting-Algorithm ) by [ hustcc] ( https://github.com/hustcc )
39
64
40
- 项目地址 :[ https://github.com/hustcc/JS-Sorting-Algorithm ] ( https://github.com/hustcc/JS-Sorting-Algorithm ) by [ hustcc ] ( https://github.com/hustcc ) 。
65
+ GitHook 在线阅读地址 :[ https://sort.hust.cc/ ] ( https://sort.hust.cc/ )
You can’t perform that action at this time.
0 commit comments