冒泡排序(以从小到大为例)原理及其优化

本文介绍了冒泡排序的基本原理,通过Java代码展示了冒泡排序的过程,并探讨了如何通过设置标志位优化排序算法,减少不必要的比较。同时,文章讨论了冒泡排序的时间复杂度,并解释了其稳定性和作为原地算法的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

冒泡排序原理

冒泡排序简要来说就是循环让相邻两个元素比较,如果左边的元素比右边的元素大,则左右交换位置,直到数组中所有元素排列完毕为止。

在这里插入图片描述

用Java代码表示:

int[] array = new int[] {22,13,45,34,89,14,64};
		
		
		for(int end = array.length; end > 0; end--) {
			for(int begin = 1; begin < end; begin++) {
				//如果前面的比后面的大,则交换
				if(array[begin] < array[begin - 1]) {
					int tmp = array[begin];
					array[begin] = array[begin - 1];
					array[begin - 1] = tmp;
				}
			}
		}
		
		for(int i = 0;i < array.length;i++) {
			System.out.print(array[i] + "_");
		}
	}

输出结果为

13_14_22_34_45_64_89_

end=array.length时,对应着找到倒数第一个元素并将其放置在最后一个位置,end=arry.length - 1时,对应着找到倒数第二个元素并将其放置在倒数第二个位置…
当end = 1时排序完成。

冒泡排序优化

上面的代码解决了排序的问题,但是性能不够高,可以继续优化。我们可以增加一个是否已经完成排序的标志,在每次扫描相邻元素的时候判断,如果某一次循环中,没有发生相邻元素更换位置,也就是已经排序完成的时候,更改这个排序的标志,从而结束后面多余的扫描判断。
代码:

int[] array = new int[] {22,13,45,34,89,14,64};
		
		
		for(int end = array.length;end > 0; end--) {
			boolean isSorted = true;
			for(int begin = 1; begin < end; begin++) {
				//如果前面的比后面的大,则交换
				if(array[begin] < array[begin - 1]) {
					int tmp = array[begin];
					array[begin] = array[begin - 1];
					array[begin - 1] = tmp;
					isSorted = false;
				}
			}
			
			if(isSorted) {
				break;
			}
		}
		
		for(int i = 0;i < array.length;i++) {
			System.out.print(array[i] + "_");
		

运行结果:

13_14_22_34_45_64_89_

没有问题。

还可以继续优化:
如果序列的尾部提前有序且都比前面的数据大,就可以记录最后一次比较的尾部位置,减少比较次数。
红框里的元素不需要再进行比较
并且再每一轮循环之后,尾部有序的元素又会增加,需要更新这部分元素。也就是记录一下每一轮最后一次交换的位置即可,以后最后一次交换也一定在这个位置之前。
Java代码:

int[] array = new int[] {22,13,45,34,89,14,64};
		
		
		for(int end = array.length;end > 0; end--) {
			int sortedIndex = 1;
			for(int begin = 1; begin < end; begin++) {
				//如果前面的比后面的大,则交换
				if(array[begin] < array[begin - 1]) {
					int tmp = array[begin];
					array[begin] = array[begin - 1];
					array[begin - 1] = tmp;
					sortedIndex = begin;
				}
			}
			end = sortedIndex;
		}
		
		for(int i = 0;i < array.length;i++) {
			System.out.print(array[i] + "_");
		}

运行结果仍然正确。

时间复杂度

最好情况,只有一次循环O(n)
最坏何平均情况,O(n^2);

**

补充:

**

稳定性

排序算法的稳定性是指两个相同的数据,在排序之后,相对位置不发生改变
假如有

351,An,2,A(n+1)

排序后是

12,An,A(n+1)35

这样的算法就是稳定的。

冒泡排序算法是稳定的。因为在判断是否交换元素时用的是<符号,也就是说如果两个元素大小相等,那么就不会交换位置,元素之间的相对位置也就没有改变。

原地算法

原地算法就是不依赖额外的资源或者依赖少数的额外资源,仅依靠输出来覆盖输入。也就是直接对元素所在的位置进行修改,不会再申请新的空间完成需求。
空间复杂度为 𝑂(1) 的都可以认为是原地算法。
因此冒泡排序是原地算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值