白话讲排序系列(二) 冒泡排序

原理,参考自数据结构(C语言版)严蔚敏:

首先,对于一个无序数列,每一趟排序,都会有一个最大的元素沉到水底。


从上图中可以看出,每经过一趟排序,最大的记录都会到达序列的末端,这是每一趟冒泡排序的过程,需要达到的目的,下面,探讨过程,如何才能每一趟实现这个目标。

条件:

  1. 需要排序的序列:49 38 65 97 76 13 27 49
  2. 排序的目标:无序数列成为升序数列

冒泡排序过程中,为了实现该目标,在每一趟排序的过程中,采取的是相邻元素交换的方式,按照指定的逻辑,交换相邻的元素,达到这个目标;下面用白话阐述一下第一趟排序的过程:

首先,49和38进行比较,发现49更大,二者交换(注意,这里必须是交换,而不是赋值操作);交换过后的结果:

38 49 65 97 76 13 27 49;

接着,49和65比较,发现满足升序关系,不进行交换;

接着,65和97比较,发现同样满足升序关系,依旧不进行交换。

接着,97和76比较,发现不满足升序,二者交换,结果变成:38 49 65 76 97 13 27 49;

接着,97和13进行比较,二者交换;结果变成:38 49 65 76 13 97 27 49;

接着,97和27进行比较,二者交换,结果变成:38 49 65 76 13 27 97 49;

接着,97和49进行比较,结果变成:38 49 65 76 13 27 49 97;

好了,现在第一趟的排序结束了,通过元素遍历交换的方式,现在最大的元素成功地沉到了水底;然后第二次排序,倒数第二大的元素继续跑到倒数第二的位置。

每一趟排序,都会有一个元素到达自己最终的位置,这是冒泡排序的一个特点;而且冒泡排序属于交换类排序。

基本思想,就是这样:相邻元素交换,最大元素沉底。

算法思想明了,接下来就是代码实现了;这里提供一种实现形式,其实只要满足这个思想,都可以叫做冒泡排序,不必拘泥于代码的内容,重在思想。

/**
package com.ccx;

/**
 * @author yuzhao.yang
 * @description:
 * @time:2018年3月6日 下午5:25:19
 */
public class BubbleSorting {
	public static void main(String[] args) {
		int a[] = new int[] { 38, 49, 65, 97, 76, 13, 27, 49, 20 };
		bubbleSort(a);
	}

	public static void bubbleSort(int a[]) {
		int len = a.length;
		// 外循环,从第一个元素开始
		for (int i = len - 1; i >= 0; i--) {
			// 相邻元素进行比较
			// 如果前面元素较大,则二者交换
			// 把i限定的元素进行相邻之间的交换
			for (int j = 0; j < i; j++) {
				if (a[j] > a[j + 1]) {
					int temp = a[j];
					a[j] = a[j + 1];
					a[j + 1] = temp;
				}
			}
		}
		for (int ele : a) {
			System.out.print(ele + " ");
		}
	}
}

代码详解:

外循环:一开始定义的i是最后一个元素的下标,把前面的所有元素都囊括在内,因为这时候需要操作的,实际上就是除了最后一个元素之外的所有元素(这句话有待商榷,因为最后一个元素也需要在内循环里操作)

内循环:对于i限定的所有元素进行相邻的交换操作,不满足升序则交换,满足升序,则不进行操作;这样,一轮过后,最大的元素就到了队列的末尾。

复杂度分析:


这里,直接从书本上截图,很容易理解其时间复杂度。

对于空间复杂度,因为牵涉到的额外空间是常数的,只需要一个空间来作交换,所以空间复杂度是O(1)。

稳定性分析:

因为比较的是相邻的两个元素,发生交换也是在这两个元素之间,如果两个元素相等,则不会发生交换,所以,相同元素的前后顺序不会发生改变,因此冒泡排序是一种稳定排序的算法。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值