本章节学习的知识点
- 插入排序
- 希尔排序
- 冒泡排序
- 堆排序
- 快速排序(hoare版本、挖坑法、前后指针法)
- 归并排序
1. 插入排序
代码如下:
2. 希尔排序
希尔排序在插入排序的基础上增加了预排序的功能,从而实现突破
(n^2)
效率的算法。
2.1 三层预排序
代码如下:
2.2 两层预排序
代码如下:
2.3 多次gap分组预排序最终实现升序效果
思路:从上面的代码我们可得,希尔排序就是通过gap分成多组进行预排序。
我们和上面一样先进行一次gap分组,将分组进行多次预排序;如果gap为3,也就是进行三组每组都要实现预排序,以此类推。
从上面结论我们可以看到,ga越大越不接近有序,gap越小越接近有序,gap为1则为插入排序。
那么我们想突破n^2
效率实现希尔排序,则可以从这个gap入手进行不断缩小gap的值,最终实现升序或者降序。
代码如下:
总结:
3. 冒泡排序
代码如下:
4. 选择排序
选择排序的核心思想是假设下标0是最小值,然后和后序数组的所有元素进行比对,找到最小值进行交换,依次类推,不断的找到次小值。
代码如下:
5. 堆排序
代码如下:
6. 快速排序
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
6.1 hoare版本
代码没有问题的情况下,产生的逻辑问题
修改以后的代码:
完整快排代码:
快速排序总结:
快排_二叉树结构排序展开图:
拓展问题 _ 1:
拓展问题 _ 2:
画图详解:
6.2 挖坑法
代码如下:
重点:不管是L还是R在移动,只要是遇到满足条件的下标,则要把当前下标后的值赋值给上一个坑位,然后当前下标变成新的坑位(坑是有滞后性的,始终慢指针一步)。最后需要把节点值重新拿来赋值最后一个相遇坑位。
6.3 前后指针法
代码如下:
前后指针单趟排序结果:
7. 快速排序优化
三数取中法,可以保证key不是一个最坏的结果
7.1 优化 _ 三数取中
在极端场景下,可能左右以及中间都是偏小的值,那么对于排序的优化微乎其微,再者采用随机值的方式,有更多可能性对于排序的帮助更大。
8. 非递归快速排序
核心思想:类似于二叉树的前序遍历,优先深度搜素。
代码如下:
9. 归并排序
归并排序的思路是以二叉树后续遍历形式找到最下面的左右子节点,然后进行排序,其次往回遍历,再通过左右子节点进行排序,依次类推直到最后回到根节点。
在归并排序中,使用后序遍历的原因是,从最开始的小区间到逐步到后面的大区间,从小区间的合并成有序数组到大区间的合并成有序数组,完美的将一个无序数组,不断的合并成一个有序数组的过程。
代码如下:
我们知道递归越往下面走,较小区间到只有一个成员的区间的过程是缓慢的,在这个过程中,我们完全可以对小区间排序进行一个优化,避免了递归的深度过于深。
我们只需要判断区间成员个数配合插入排序对小区间排序进行一个优化。
10. 归并排序(非递归)
区间存在越界情况:
方案一 _ 区间越界结束循环:
方案二 _ 区间越界修正区间:
11. 快速排序_优化(三路划分)
画图详解:
代码如下:
12. 非比较排序(计数排序)
-
根据排序进行计算每个数字出现的次数
-
根据每个数字出现的次数进行重新排序
缺陷:
- 依赖数据范围,适合数据集中场景
- 只能在整型数据中使用
代码如下:
本章完~