经典算法——冒泡排序
1. 什么是算法?
任何被明确定义的计算过程都可以称作 算法 ,它将某个值或一组值作为输入,并产生某个值或一组值作为输出。所以 算法可以被称作将输入转为输出的一系列的计算步骤 。
说白了就是步骤明确的解决问题的方法。由于是在计算机中执行,所以通常先用伪代码来表示,清晰的表达出思路和步骤,这样在真正执行的时候,就可以使用不同的语言来实现出相同的效果。
2. 算法的效率
算法效率是指算法 执行的时间,算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。在现在的计算机硬件环境中,比较少需要考虑这个问题了,特别是pc机的编程, 内存空间 越来越大,所以被考虑得也越来越少,不过一个好的程序员,都应该对自己的程序有要求,每一个for比别人少一次判断1000个for就能够少掉很多的运行时间。所以能够理解,能够大概的去运用"效率度量"还是有很大意义的。我们一般通过两个方面来衡量一个算法的效率
- 时间复杂度?
算法的时间复杂度是一个函数,它定性描述一个算法的运行时间。 一个算法的执行所需要的时间,从理论上来说是算不出来的,必须通过上机测试才能得到,但这并不是说我们对于每个算法都要上机测试,我们只需要知道哪个算法所花的时间多,哪个算法所花的时间少就行。 一个算法花费的时间与算法中的语句执行次数成正比,算法中的语句执行次数越多,它花费的时间就越多。一个算法中的语句执行次数成为语句频度或时间频度,记为T(n),n为问题的规模。
- 空间复杂度?
空间复杂度是指执行这个算法所需要的内存空间。 空间复杂度需要考虑在运行过程中为 局部变量分配的存储空间的大小 ,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。 空间复杂度也就是对一个算法在运行过程中 临时占用存储空间大小 的量度,记做S(n)=O(f(n))。比如直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1) 。
- 稳定性?
算法稳定性指的是在一组待排序记录中,如果存在任意两个相等的记录R和S,且在待排序记录中R在S前,如果在排序后R依然在S前,即它们的前后位置在排序前后不发生改变,则称为排序算法为稳定的。
常见排序算法的稳定性:堆排序、快速排序、希尔排序、直接选择排序是不稳定的排序算法,而基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法。
3. 冒泡排序
冒泡排序,也被称为气泡排序或泡沫排序。
冒泡排序是一种较简单的排序算法。它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。重复此操作,直到整个数列都有序为止!
3.1 代码实践
java代码
/**
* 冒泡排序
*
* @param a 待排序的数组
* @param n 数组的长度
*/
public static void bubbleSort1(int[] a, int n) {
int i, j;
for (i = n - 1; i > 0; i--) {
// 将a[0...i]中最大的数据放在末尾
for (j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
// 交换a[j]和a[j+1]
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
}
/**
* 冒泡排序(改进版)
*
* @param a 待排序的数组
* @param n 数组的长度
*/
public static void bubbleSort2(int[] a, int n) {
int i, j;
int flag; // 标记
for (i = n - 1; i > 0; i--) {
// 初始化标记为0
flag = 0;
// 将a[0...i]中最大的数据放在末尾
for (j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
// 交换a[j]和a[j+1]
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
flag = 1; // 若发生交换,则设标记为1
}
}
if (flag == 0)
break; // 若没发生交换,则说明数列已有序。
}
}
public static void main(String[] args) {
int i;
int[] a = {20, 40, 30, 10, 60, 50};
System.out.printf("before sort:");
for (i = 0; i < a.length; i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
bubbleSort1(a, a.length);
// bubbleSort2(a, a.length);
System.out.printf("after sort:");
for (i = 0; i < a.length; i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
}
3.2 算法效率
- 时间复杂度
假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(n),需要遍历多少次呢?n-1次!因此,冒泡排序的时间复杂度是O(n2)。
- 空间复杂度
冒泡排序的辅助变量空间仅仅是一个临时变量,并且不会随着排序规模的扩大而进行改变,所以空间复杂度为O(1)。
- 稳定性
冒泡排序是针对相邻的元素且存在相对大小时才交换元素位置,对于大小相等的相邻元素,不会交换两者位置,所以冒泡排序是稳定的。
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的