冒泡排序(Bubble Sort)

本文详细介绍了冒泡排序的原理,包括其最优和最差的时间复杂度,以及稳定性。通过实例展示了冒泡排序的过程,并提出了当某一轮无交换发生时可提前结束排序的优化策略。

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

关键思想

顺序依次比较相邻两个元素,倒序则交换。

时间复杂度

Time ComplexityValue
最优时间复杂度 O ( n ) O(n) O(n)
最差时间复杂度 O ( n 2 ) O(n^{2}) O(n2)
平均时间复杂度 O ( n 2 ) O(n^{2}) O(n2)

解析:
1)最优时间复杂度:输入序列( n u m = n num=n num=n)自身顺序时,仅需一轮 n − 1 n-1 n1次比较便可结束。
2)最差时间复杂度:输入序列( n u m = n num=n num=n)自身倒序时,一共需要经过 n − 1 n-1 n1轮才可结束。具体而言,即第 i i i轮冒泡排序需比较 n − i n-i ni次,交换 3 ( n − i ) 3(n-i) 3(ni)次,则共需比较 ∑ i = 1 n − 1 = n ( n − 1 ) 2 \displaystyle\sum_{i=1}^{n-1}=\frac {n(n-1)} 2 i=1n1=2n(n1)次,交换 3 ∑ i = 1 n − 1 = 3 n ( n − 1 ) 2 3\displaystyle\sum_{i=1}^{n-1}=3\frac {n(n-1)} 2 3i=1n1=32n(n1)次。

空间复杂度

Space ComplexityValue
空间复杂度O(1)

稳定性 √

解析:
稳定性:若原序列中数 i i i位于数 j j j前面,且 i = j i=j i=j,整个排序过程结束之后数 i i i仍位于数 j j j前面。

实例:[6 3 8 2 9 1](Java)

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		System.out.println("请键盘输入整数序列[例如:6 3 8 2 9 1 end]");  // 从键盘接收输入信息
		Scanner list = new Scanner(System.in);
		ArrayList<Integer> inputArray = new ArrayList<Integer>();
		while (list.hasNextInt()) {
			inputArray.add(list.nextInt());
		}  // 输入--非数字--结束输入过程
		list.close();
        System.out.println("输入:" + inputArray);
//        End2Start(inputArray);  // Case1: start ← end
//        Start2End(inputArray);  // Case2: start → end
        End2StartImprove(inputArray);  // Case3: start ← end[优化]
	}

Case1:左 ← 右(从小到大排序)

Case1:左 ← 右(从小到大排序)

// Case1: start ← end
	public static void End2Start(ArrayList<Integer> inputArray) {
		for (int i = 0; i < inputArray.size() - 1; i++) {
			System.out.println("第" + (i + 1) + "轮" + "冒泡排序");
			for (int j = inputArray.size() - i - 1; j > 0; j--) {
				if (inputArray.get(j) < inputArray.get(j - 1)) {
					System.out.print(inputArray.get(j) + "<" + inputArray.get(j - 1) + " → 交换 → ");
					int temp = inputArray.get(j);
					inputArray.set(j, inputArray.get(j - 1));
					inputArray.set(j - 1, temp);
					System.out.println(inputArray);
				}
				else
					System.out.println(inputArray.get(j) + ">" + inputArray.get(j - 1) + " → 不交换 → " + inputArray);
			}			
			System.out.println("End:" + inputArray);
		}
		System.out.println("输出:" + inputArray);
	}

Case2:左 → 右(从小到大排序)

Case2:左 → 右(从小到大排序)

// Case2: start → end
	public static void Start2End(ArrayList<Integer> inputArray) {
		for (int i = 0; i < inputArray.size() - 1; i++) {
			System.out.println("第" + (i + 1) + "轮" + "冒泡排序");
			for (int j = 0; j < inputArray.size() - i - 1; j++) {
				if (inputArray.get(j) > inputArray.get(j + 1)) {
					System.out.print(inputArray.get(j) + ">" + inputArray.get(j + 1) + " → 交换 → ");
					int temp = inputArray.get(j);
					inputArray.set(j, inputArray.get(j + 1));
					inputArray.set(j + 1, temp);
					System.out.println(inputArray);
				}
				else
					System.out.println(inputArray.get(j) + "<" + inputArray.get(j + 1) + " → 不交换 → " + inputArray);
			}			
			System.out.println("End:" + inputArray);
		}
		System.out.println("输出:" + inputArray);
	}

Case3:左 ← 右【优化】(从小到大排序)

思考:某一轮冒泡排序过程中无任何交换时,说明已经有序,结束。
1)Case1[6 3 8 2 9 1]:第4轮冒泡排序过程开始已无交换过程;
2)Case2[6 3 8 2 9 1]:最后一轮冒泡排序过程依旧包含交换过程;
3)Case1与Case2[6 3 8 2 9 1]:总交换次数相等,总比较次数相等。
结论:优化只针对Case1有效!

// Case3: start ← end[优化]
	public static void End2StartImprove(ArrayList<Integer> inputArray) {
		int i = 0;
		boolean change = false;
		do 
		{
			change = true;
			System.out.println("第" + (i + 1) + "轮" + "冒泡排序");
			for (int j = inputArray.size() - i - 1; j > 0; j--) {
				if (inputArray.get(j) < inputArray.get(j - 1)) {
					System.out.print(inputArray.get(j) + "<" + inputArray.get(j - 1) + " → 交换 → ");
					int temp = inputArray.get(j);
					inputArray.set(j, inputArray.get(j - 1));
					inputArray.set(j - 1, temp);
					System.out.println(inputArray);
					change = false;
				}
				else
					System.out.println(inputArray.get(j) + ">" + inputArray.get(j - 1) + " → 不交换 → " + inputArray);
			}
			i++;
			System.out.println("End:" + inputArray);
		}
		while((i < inputArray.size() - 1) && (change == false));
		System.out.println("输出:" + inputArray);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值