您的位置:首页 > 其它

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

2018-03-06 17:43 337 查看
原理,参考自数据结构(C语言版)严蔚敏:
首先,对于一个无序数列,每一趟排序,都会有一个最大的元素沉到水底。



从上图中可以看出,每经过一趟排序,最大的记录都会到达序列的末端,这是每一趟冒泡排序的过程,需要达到的目的,下面,探讨过程,如何才能每一趟实现这个目标。
条件:
需要排序的序列:49 38 65 97 76 13 27 49
排序的目标:无序数列成为升序数列
冒泡排序过程中,为了实现该目标,在每一趟排序的过程中,采取的是相邻元素交换的方式,按照指定的逻辑,交换相邻的元素,达到这个目标;下面用白话阐述一下第一趟排序的过程:
首先,49和38进行比较,发现49更大,二者交换(注意,这里必须是交换,而不是赋值操作);交换过后的结果:
38 49 65 97 76 13 27 49;
接着,49和65比较,发现满足升序关系,不进行交换;
接着,65和97比较,发现同样满足
4000
升序关系,依旧不进行交换。
接着,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)。
稳定性分析:
因为比较的是相邻的两个元素,发生交换也是在这两个元素之间,如果两个元素相等,则不会发生交换,所以,相同元素的前后顺序不会发生改变,因此冒泡排序是一种稳定排序的算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: