冒泡排序法又称为交换排序法,是由观察水中冒泡变化构思而成,气泡随着水深压力而改变。气泡在水底时,压力最大,气泡最小;当慢慢浮上水面时,发现气泡由小渐渐变大。
冒泡排序法的比较方式由第一个元素开始,比较相邻元素大小,若大小顺序有误,则对调后再进行下一个元素的比较。如此扫描过一次之后就可确保最后一个元素是位于正确的顺序。接着再逐步进行第二次扫描,直到完成所有元素的排序关系为止。
演算过程
由此可知 5 个元素的冒泡排序法必须执行 5~1 次扫描,第一次扫描需比较 5~1 次,共比较 4+3+2+1 次
冒泡法分析
- 最坏的情况及平均情况均需比较 (n-1)+(n-2)+(n-3)+...+3+2+1=n(n-1)/2 次;时间复杂度为 O(n^2),最好的情况只需完成一次扫描,发现没有做交换的操作则表示已经排序完成,所以只做了 n-1 次比较,时间复杂度为 O(n)。
- 由于冒泡排序为相邻两者相互比较对调,并不会更改其原本排序的顺序,所以是稳定排序法。
- 只需一个额外的空间,所以空间复杂度为最佳。
- 此排序适用于数据量小或有部分数据已经过排序的情况。
example1
/** * 传统冒泡排序法 * */ public class BubbleSort { public static void main(String[] args) { int[] data = {6, 5, 9, 7, 2, 8}; int temp; System.out.print("原始数据为:"); for (int i : data) { System.out.print("[" + i + "]"); } System.out.println(); for (int i = data.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) { if (data[j] > data[j + 1]) { temp = data[j]; data[j] = data[j + 1]; data[j + 1] = temp; } }// 扫描后的结果 System.out.print("第 " + (data.length - i) + " 次结果:"); for (int k : data) { System.out.print("[" + k + "]"); } System.out.println(); } System.out.print("排序后结果:"); for (int i : data) { System.out.print("[" + i + "]"); } } }
由上面的程序可以看出冒泡排序法有一个缺点,即不管数据是否已排序完成都固定会执行 n(n-1)/2 次,而我们可以通过在程序中加入判断来判断何时提前中断程序,又可得到正确的数据,来提高程序执行效率。
example2
/** * 传统冒泡排序法 * */ public class BubbleSort { public static void main(String[] args) { int[] data = {6, 5, 9, 7, 2, 8}; int temp; System.out.print("原始数据为:"); for (int i : data) { System.out.print("[" + i + "]"); } System.out.println(); for (int i = data.length - 1; i > 0; i--) { boolean isYes = true; for (int j = 0; j < i; j++) { if (data[j] > data[j + 1]) { temp = data[j]; data[j] = data[j + 1]; data[j + 1] = temp; isYes = false; } } if (isYes) { break; } // 扫描后的结果 System.out.print("第 " + (data.length - i) + " 次结果:"); for (int k : data) { System.out.print("[" + k + "]"); } System.out.println(); } System.out.print("排序后结果:"); for (int i : data) { System.out.print("[" + i + "]"); } } }