各位读者好, 我是小陈, 这是我的个人主页
小陈还在持续努力学习编程, 努力通过博客输出所学知识
如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽
希望我的专栏能够帮助到你:
JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)
本篇继续分享七大排序算法中的 冒泡排序 , 其余六个算法也有介绍噢
想看哪个点哪个 : 直接插入排序, 选择排序, 希尔排序, 堆排序, 快速排序, 归并排序
提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎评论区指点~ 废话不多说,直接发车~
排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作
以 int 类型数据从小到大排序为例:
排序前:4,1,3,6,8,7,2,5
排序后:1,2,3,4,5,6,7,8
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
以 int 类型数据从小到大排序为例:
排序前:4,1,3a,6,8,7,2,3b,5(3a 在 3b 之前)
排序后:1,2,3a,3b,4,5,6,7,8(3a 还在 3b 之前,稳定)
排序后:1,2,3b,3a,4,5,6,7,8(3a 不在 3b 之前,不稳定)
以下是常见的 7大排序 算法
冒泡排序是一种交换排序, 它的基本思想是 : 两两比较相邻记录的关键字, 如果反序则交换, 直到有序为止
冒泡应该是最早接触的一种排序算法了, 因为它很简单易懂, 尽管如此, 还是来看一看冒泡的图解过程:
注意 i , j 下标的变化
❓❓❓为什么 每趟冒泡排序之后, i++; 而 j 总是从 0 下标开始呢
因为一趟冒泡结束后只是做到了把 待排序数据的最大值 放在 待排序数据的最后, 而最小值不一定在最前面, 所以 i 要从 0 下标开始重新找目前待排序数组的最大值, 让他往后放, 循环往复, 最后剩下的那个数据一定是最小的
/**
* 冒泡排序
* 时间复杂度:最坏 O(N*N) 最好 O(N)
* 时间复杂度:O(1)
* 稳定性:稳定
*/
public static void bubleSort(int[] array){
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
}
其实 j < array.length - i - 1;
这一句代码也是经过简单的优化的, 避免了 j 的无效循环
但这 还是存在效率较低 的情况, 当 待排数据有序 时, i 还是会继续遍历, 从而带动 j 的遍历, 是纯纯浪费❌
所以对上述代码的优化方案是 :
每次 i 开始循环时 定义一个标记 false
, 如果 j 遍历完数组, 发生了交换, 把 false 改成 true
, 如果 j 的循环结束发现标记还是false, 说明什么?
说明没有发生交换, 待排数据是整体有序的, 那么就不让 i 继续遍历了, 直接返回即可
优化后代码:
public static void bubleSort(int[] array){
for (int i = 0; i < array.length; i++) {
boolean mark = false;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
mark = true;
}
}
if (mark == false) {
return;
}
}
}
时间复杂度 :
最好情况下(数组整体有序),也需要 j 遍历一遍数组,时间复杂度是O(N)
最坏情况下(数组逆序),此时时间复杂度是O(N2)
空间复杂度 :
没有额外空间的开销,只有常数个记录的辅助空间,空间复杂度是O(1)
稳定性 :
稳定
只要是交换时, 两数据相邻就是稳定的算法,只要是跳跃式的交换就是不稳定, 当然别忘了, 稳定的算法也可以修改代码更改成不稳定的
建议对七大算法都有认识之后, 再对比分析~~
想看哪个点哪个 : 直接插入排序, 选择排序, 希尔排序, 堆排序, 快速排序, 归并排序
没有完美的排序算法,任何一种算法都是有优点和缺陷的,即便是大名鼎鼎的快速排序,也只是整体上效率比较高,性能相对更优越
现在就整体分析一下各种排序的优缺点
早期的排序算法平均时间复杂度都是O(N2); 因为原理比较简单, 但性能较差, 所以 一般把直接插入排序,选择排序,冒泡排序归为简单排序一类, 另外四种排序都归于 改进排序
从平均情况看:
改进过的排序: 希尔排序, 堆排序, 归并排序, 快速排序要胜过简单排序的性能, 而四个改进算法中, 希尔排序的性能最差
时间复杂度:
直接插入排序和冒泡排序最快
从最好情况看从最坏情况看:
堆排序和归并排序的性能更胜过快排和其他简单排序
综合来看:
堆排序和归并排序比较稳定和强大, 情况最坏时好用
直接插入排序和冒泡排序, 最好情况时最好用,
而快速排序比较极端, 最好最坏情况都有缺陷 但是 快速排序能够称之为快速排序, 是因为它的综合性能最强,一般情况下是最快的
从稳定性来看:
改进排序中只有归并排序
从数据个数上看:
数据量越少, 越适合用简单排序, 因为堆排, 快速排序, 归并排序, 都用到了递归, 对于少量数据排序有点"炮弹打蚊子"
只要是交换时, 两数据相邻就是稳定的算法,只要是跳跃式的交换就是不稳定, 当然别忘了, 稳定的算法也可以修改代码更改成不稳定的
如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦~
上山总比下山辛苦
下篇文章见