冒泡排序的本質(zhì)是對列表中的元素進行兩兩對比,然后根據(jù)條件(一般是比較兩個元素的大小)進行兩個元素的交換。
在冒泡排序中有一個重要的思想就是凡是涉及到排序的算法,我們一般會將列表區(qū)分成已排序和未排序兩部分,我們只需要對未排序的部分進行排序即可。
冒泡排序我們默認將列表左邊部分劃為未排序部分,右邊部分劃為已排序部分,冒泡操作即為每次從未排序部分中篩選出最大值放入已排序部分。在列表未進行排序的情況下未排序部分占據(jù)整個列表長度,已排序部分長度為0.接下來我們看一下具體實現(xiàn):
package com.lijianjian.test;
public class BubbleSort {
public static void main(String[] args) {
int[] aa = { 102, 100, 108, 27, 19, 22 };
bubbleSort(aa);
for (int i = 0; i < aa.length; i++) {
System.out.println("value=" + aa[i]);
}
}
/**
* 冒泡排序的原理即是將列表抽象為未排序和已排序兩部分 對未排序的部分進行冒泡操作
* 冒泡操作即是從未排序的元素中篩選出最大值放入已排序部分(元素篩選的本質(zhì)是元素的交換)
*/
private static void bubbleSort(int[] aa) {
// 用來表示本次冒泡操作是否進行了數(shù)據(jù)的交換,如果false則表示數(shù)據(jù)排序已完成
// 當(dāng)一次冒泡操作中沒有進行過數(shù)據(jù)交換則表示當(dāng)前未排序的部分的數(shù)據(jù)默認就是有序的,所以后續(xù)的冒泡操作便不需要執(zhí)行,避免不必要的數(shù)據(jù)比較
boolean hasChanged = false;
for (int i = aa.length - 1; i > 0; i--) {
// 外層循環(huán)進行排序次數(shù)的限制 i表示未排序元素的最大坐標(biāo),i>0表示當(dāng)未排序元素只有一個的時候就不需要在進行冒泡操作了
// 在第一次排序前未排序的部分長度為列表的總長度,每進行一次排序 列表中未排序部分都會減少一個
System.out.printf("第%d次執(zhí)行冒泡操作,未排序元素數(shù)量%d\n", aa.length - i, i+1);
hasChanged = false;
for (int j = 0; j < i; j++) {
// 依次兩兩比較并按照條件交換的冒泡操作(必須保證有兩個元素才能比較)
// j < i 同時也表示 最多執(zhí)行的對比操作為i次
if (aa[j + 1] < aa[j]) {
aa[j] = aa[j + 1] + aa[j];
aa[j + 1] = aa[j] - aa[j + 1];
aa[j] = aa[j] - aa[j + 1];
hasChanged = true;
}
}
if (!hasChanged) {
break;
}
}
}
}