排序算法分类
稳定 :( 插入、冒泡、归并)
非稳定 (不稳定) :(选择、快排)
内部 :(整体一次性的加入到内存当中,整体的去排序)
外部 : (对一个数据文件排序的话可以不将整个文件都加载到内存里面进行排序 - 归并! )
插入排序 (insert_Sort)
口诀 :
- 将数组分成【已排序区】 和 【待排序区】
- 将【待排序区】第一个元素,向前插入到【已排序区】
- 直到【待排序区】没有元素为止
时间复杂度分析
最好 :0 次
最坏 :n - 1 次
平均复杂度 :( 最好 + 最坏 ) / 2 : $\frac{(n - 1)}{2} * N$ : $O(N^2)$
代码实现 - 模块
1 | // 插入排序 |
冒泡排序 (bubble_Sort)
口诀 :
- 将数组分成【已排序区】 和 【待排序区】
- 从头到尾扫描【待排序区】,若前面元素比后面元素大,则交换
- 每一轮都会将【待排序区】中最大的放到【已排序区】的开头
- 直到【待排序区】没有元素为止
小优化 : 如果一轮中一次交换都没有就证明序列已经有序可以提前结束
时间复杂度
平均复杂度 : $O(N^2)$
代码实现 - 模块
1 | // 冒泡排序 |
归并排序 - 二路归并 (merge_Sort)
核心思想分治
将【待排序数组】分为两个部分
如 : 9 7 8 5 4 1 2 3 6 5
分为 : 9 7 8 5 4 — 1 2 3 6 5
再分:9 7 — 8 5 4 — 1 2 — 365
达到足够小并且立马能拿到答案的规模
上一层 : 【 — 我是空数组 — 】
可以得到 7 9 — 4 5 8 — 1 2 — 3 5 6 组内有序组间无序
一个指向👆 ____👆 合并成一个有序数组 - 在拷贝到原数组
他们两个比较谁小就插入到上面数组
时间复杂度
平均复杂度 : $O(Nlog^N)$
代码实现 - 模块
1 | // 归并排序 |
稳定排序代码合集 - 插入、冒泡、归并
1 | /************************************************************************* |
选择排序 (select_Sort)
口诀 :
- 将数组分成【已排序区】 和 【待排序区】
- 每一轮从【待排序区】中选择一个最小的元素方到【已排序区】的尾部
- 直到【待排序区】没有元素为止
时间复杂度
平均复杂度 : $O(N^2)$
代码实现 - 模块
1 | // 选择排序 |
快速排序 (quick_Sort)
口诀 :
- 选择基准数 : 一般选择序列的第一个数 (基准值)
- 进行(partition)操作:作用就是使得待排序的序列分为了两部分
- 前部分都小于基准值 — 后面一部分都大于基准值 (一轮partition 操作)
- head = 第一个数(基准值) tail = 最后一个元素
- tail 操作
- 从后往前找第一个小于基准值的数 - 找到之后填到头指针的位置
- head 操作
- 从前往后找到找到一个大于基准值的数 - 找到之后填到尾针的位置
时间复杂度
平均复杂度 : $O(Nlog^N)$
完全逆序 : $ O(N^2)$ - (就变成了选择排序)
代码实现 - 模块 - 未优化 - 填坑法
1 | // 快排 — 第一版 |
代码实现 - 模块 - 优化 - 基准值两点取中法、无监督优化(去掉x < y)、单边递归法
1 | // 快排 — 第二版 基准值两点取中法、无监督优化(去掉x < y)、单 边递归法 |
不稳定排序代码合集 - 选择、快速、快速优化
1 | /************************************************************************* [0] |
有趣的知识
1 | g++ test.cpp |