秋招之路-动画演示十大经典排序算法_排序算法

[图]green pencil 2019-06-25 

这是 herongwei 的第 68 篇原创

阅读本文大概需要 6.66 分钟

前言-排序

排序算法是《数据结构与算法》中最基本的算法之一。

排序算法可以分为内部排序和外部排序。

内部排序是数据记录在内存中进行排序。

而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。

用两张图来概括:

秋招之路-动画演示十大经典排序算法_排序算法_02

秋招之路-动画演示十大经典排序算法_数组_03

今天我将换一种形式,以动画形式,尽可能通俗易懂的讲解经典排序算法的精髓,希望能帮助大家更好的掌握。

PS :我本人制作的 GIF 图片超过 300 帧,无法上传,弄了半天不知道咋解决,引用了公众号【五分钟学算法】图片,特此说明。

PPS:动画演示GIF加载有点慢,请稍等片刻。

1、冒泡排序

1、一开始交换的区间是 0-N-1,第一个数和第二个数进行比较,哪个大就放到后面,然后第二个数个第三个数进行比较,把大的放后面,依次交换,最大的数会最终放在数组的最后面。

2、然后缩小范围,0-N-2,进行 1 的操作,第二大的数会放在数组的倒数第二的位置,这样依次进行 1 的操作,直到剩下最后一个数的时候,所有数有序。

3、复杂度 O(n^2)。

动画演示:

 冒泡排序

秋招之路-动画演示十大经典排序算法_数据_04

2、选择排序

1、选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。

2、直到所有元素有序。

3、复杂度 O(n^2)。

动画演示:

 选择排序

秋招之路-动画演示十大经典排序算法_排序算法_05

3、插入排序

1、将数组分为已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。

2、核心思想:取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。

3、重复这个过程,直到未排序区间中元素为空,算法结束。

4、复杂度 O(n^2)。

动画演示:

 插入排序

秋招之路-动画演示十大经典排序算法_数组_06

4、希尔排序

1、1959 年 Shell 发明,第一个突破 O(n^2) 的排序算法,希尔排序是插入排序的改良版。

2、它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

3、插入排序中,插入的步长是 1,希尔排序的步长是逐渐调整的,准确来说是从大到小。

4、如下图所示,依次调整,最开始的 6 5 8 三个元素是不需要考虑的。从 1 开始,比较跳之前最开始的元素如果比自己大且没有越界,则向前跳三位。

动画演示:

希尔排序

秋招之路-动画演示十大经典排序算法_数组_07

5、快速排序

1、快排的思想:如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)。

2、遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。

3、经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。

4、根据分治、递归的处理思想,递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了。

5、取 a[l] 作为切分元素,然后从数组的左端向右扫描直到找到第一个大于等于它的元素,再从数组的右端向左扫描找到第一个小于它的元素,交换这两个元素。不断进行这个过程,就可以保证左指针 i 的左侧元素都不大于切分元素,右指针 j 的右侧元素都不小于切分元素。当两个指针相遇时,将切分元素 a[l] 和 a[j] 交换位置。

动画演示:

 快速排序

秋招之路-动画演示十大经典排序算法_数组_08

一次完整的划分操作时如何的?

1、先取划分元素 P 放到最后面,然后构建一个小于等于区间 T 放在最前面。

2、依次从左到右遍历,如果遇到大于 P 的元素则跳过继续遍历,遇到小于等于 P 的元素时候,将当前元素和区间 T 的下一个元素进行交换。然后将区间 T 往右扩展一个位置。

3、这样依次遍历,直到区间 T 的下一个元素等于划分元素 P。

4、这样就是一次完整的划分过程,时间复杂度为 O(N)。

6、归并排序

1、可以看做两两元素排序,到四四元素排序,到八八元素排序,合并所有元素,直到所有元素有序。

2、归并排序使用的就是分治思想。分治,顾名思义,就是分而治之,将一个大问题分解成小的子问题来解决。小的子问题解决了,大问题也就解决了。

动画演示:

归并排序

秋招之路-动画演示十大经典排序算法_排序算法_09

7、堆排序

1、首先将所有元素建成一个大小为 N 的大根堆,堆顶是所有元素的最大值,把堆顶元素和最后元素交换,把最大值移除堆,放在有序数组保存,堆元素减一。

2、将 N-1 个元素的堆进行调整为大根堆,执行 1 操作,把堆顶元素和最后元素交换,把最大值移除堆,放在有序数组保存,堆元素减一。

3、继续以上步骤,堆的大小依次减一,有序数组元素依次增加,当堆大小减为 1 ,此时整个数组有序。

动画演示:

堆排序

秋招之路-动画演示十大经典排序算法_数组_10

8、计数排序

1、花O(n)的时间扫描一下整个序列 A,获取最小值 min 和最大值 max。

2、开辟一块新的空间创建新的数组 B

长度为 ( max - min + 1)。

3、数组 B 中 index 的元素记录的值是 A 中某元素出现的次数。

4、最后输出目标整数序列,具体的逻辑是遍历数组 B,输出相应元素以及对应的个数。

动画演示:

计数排序

秋招之路-动画演示十大经典排序算法_排序算法_11

9、桶排序

桶排序 (Bucket sort) 是一种基于计数的排序算法(计数排序可参考上节的内容),工作的原理是将数据分到有限数量的桶子里,然后每个桶再分别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序)。

1、设置固定数量的空桶。

2、把数据放到对应的桶中。

3、对每个不为空的桶中数据进行排序。

4、拼接不为空的桶中数据,得到结果。

动画演示:

桶排序

秋招之路-动画演示十大经典排序算法_数据_12

10、基数排序

将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零

1、从最低位开始,依次进行一次排序。

2、从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

动画演示:

基数排序

秋招之路-动画演示十大经典排序算法_排序算法_13

欢迎大家一起交流~

秋招之路-动画演示十大经典排序算法_数据_14