冒泡排序(java)

过程: 冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作。

示意图:
在这里插入图片描述
第一,冒泡排序是原地排序算法吗?

冒泡的过程只涉及相邻数据的交换操作,只需要常量级的临时空间,所以它的空间复杂度为O(1),是一个原地排序算法

第二,冒泡排序是稳定的排序算法吗?

在冒泡排序中,只有交换才可以改变两个元素的前后顺序。为了保证冒泡排序算法的稳定性,当有相邻的两个元素大小相等的时候,我们不做交换,相同大小的数据在排序前后不会改变顺序,所以冒泡排序是稳定的排序算法。

第三,冒泡排序的时间复杂度是多少?

最好情况下,要排序的数据已经是有序的了,我们只需要进行一次冒泡操作,就可以结束了,所以最好情况时间复杂度是O(n)。而最坏的情况是,要排序的数据刚好是倒序排列的,我们需要进行 n 次冒泡操作,所以最坏情况时间复杂度为O(n2)

初始版:

import java.util.Arrays;

public class Main {
	public static void bubble1(int[] arr) {
		for(int i = 1;i < arr.length;i++) {// 循环 length - 1 次
			for(int j = 0;j < arr.length - i;j++) {
				if(arr[j] > arr[j + 1]) {
					int tmp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = tmp;
 				}
			}
		}
	}
	public static void main(String[] args) {
		int[] arr = {1,3,2,6,4,0,8,5,9,7};
		bubble1(arr);
		System.out.println(Arrays.toString(arr));
	}
}

优化版:加个 flag 标志位

public static void bubble2(int[] arr) {
	for(int i = 1;i < arr.length;i++) {// 循环 length - 1 次
		boolean flag = false;//true表示发生了数据交换
		for(int j = 0;j < arr.length - i;j++) {
			if(arr[j] > arr[j + 1]) {
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = true;
			}
		}
		if(!flag) break;//如果此趟冒泡没有数据交换,说明已经有序了
	}
}

终极优化版:在每一轮排序后记录最后一次元素交换的位置,作为下次比较的边界, 对于边界外的元素在下次循环中无需比较。

public static void bubble1(int[] arr) {
	// 最后一次交换的位置
    int lastExchange = 0;
    // 无序数据的边界,每次只需要比较到这里即可退出
    int sortBorder = arr.length - 1;
	for(int i = 1;i < arr.length;i++) {// 循环 length - 1 次
		boolean flag = false;//true表示发生了数据交换
		for(int j = 0;j < sortBorder;j++) {
			if(arr[j] > arr[j + 1]) {
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = true;
				// 更新最后一次交换的位置
                lastExchange = j;
			}
		}
		sortBorder = lastExchange;
		if(!flag) break;
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值