Java排序算法之冒泡排序的原理及優(yōu)化
冒泡排序原理
冒泡排序的思想很簡(jiǎn)單:遍歷數(shù)組,比較相鄰的兩個(gè)元素,順序錯(cuò)誤就把它們交換,直到整個(gè)數(shù)組排序完成。因?yàn)槊拷?jīng)過(guò)一趟排序,越小的元素會(huì)經(jīng)交換而慢慢“浮”到數(shù)列的頂端,因此叫做冒泡排序。

假設(shè)我們現(xiàn)在要對(duì)數(shù)組:arr= {3,9,-1,10,-2,5,21} 進(jìn)行排序,結(jié)合上面的動(dòng)圖,經(jīng)過(guò)第一趟排序后最大的元素會(huì)被排到最后。
第一趟排序
public int[] OneStepBubbleSort(int arr[]){
int temp = 0;
for (int i = 0; i < arr.length - 1; i++){
if (arr[i] > arr[i + 1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.print("第1趟排序完成:");
System.out.println(Arrays.toString(arr));
return arr;
}測(cè)試:
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2, 5, 21};
SortTest sortTest = new SortTest();
sortTest.OneStepBubbleSort(arr);
}
結(jié)果:

那么第二趟排序后第二大的元素10會(huì)被排到倒數(shù)第二的位置。
第二趟排序
public int[] TwoStepBubbleSort(int arr[]){
int temp = 0;
for (int i = 0; i < arr.length - 1 - 1; i++){
if (arr[i] > arr[i + 1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.print("第2趟排序完成:");
System.out.println(Arrays.toString(arr));
return arr;
}
測(cè)試:
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2, 5, 21};
SortTest sortTest = new SortTest();
sortTest.OneStepBubbleSort(arr);
sortTest.TwoStepBubbleSort(arr);
}
結(jié)果:

第三趟排序
public int[] ThreeStepBubbleSort(int arr[]){
int temp = 0;
for (int i = 0; i < arr.length - 1 - 2; i++){
if (arr[i] > arr[i + 1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
System.out.print("第3趟排序完成:");
System.out.println(Arrays.toString(arr));
return arr;
}
測(cè)試:
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2, 5, 21};
SortTest sortTest = new SortTest();
sortTest.OneStepBubbleSort(arr);
sortTest.TwoStepBubbleSort(arr);
sortTest.ThreeStepBubbleSort(arr);
}
結(jié)果:

如此類推,每一趟排序中不同的地方在于循環(huán)的終止條件:arr.length - 1 和 arr.length - 1 - 1 和 arr.length - 1 - 2 等等,那么只需要在此循環(huán)外面再包一層循環(huán)即可。最終代碼為:
冒泡排序算法代碼
public int[] BubbleSort(int arr[]){
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1 ; j++) {
if (arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.print("第" + (i + 1) + "趟排序完成:");
System.out.println(Arrays.toString(arr));
}
return arr;
}
測(cè)試:
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2, 5, 21};
SortTest sortTest = new SortTest();
System.out.println();
sortTest.BubbleSort(arr);
}
結(jié)果:

改進(jìn)冒泡排序
從上面冒泡排序的結(jié)果可以看出,總共進(jìn)行了6趟排序,但從第4躺開始數(shù)組就已經(jīng)排序完畢了,后面的兩趟排序相當(dāng)于在做無(wú)用的比較。
為了解決此問(wèn)題,我們可以進(jìn)行優(yōu)化,思想是:如果發(fā)現(xiàn)在某一趟排序中沒(méi)有發(fā)生過(guò)一次交換,那么可以提前結(jié)束冒泡排序。實(shí)現(xiàn)方法是設(shè)置一個(gè)flag變量來(lái)記錄是否發(fā)生過(guò)交換:
public int[] BubbleSort(int arr[]){
int temp = 0;
boolean flag = false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1 ; j++) {
if (arr[j] > arr[j + 1]){
flag = true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
// 判斷flag
if (!flag){
// 如果flag是false,則退出
break;
}else {
// flag為true,說(shuō)明發(fā)生過(guò)交換,那么在進(jìn)行下一趟前需要把flag重新置為false
flag = false;
}
System.out.print("第" + (i + 1) + "趟排序完成:");
System.out.println(Arrays.toString(arr));
}
return arr;
}
測(cè)試:
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2, 5, 21};
SortTest sortTest = new SortTest();
System.out.println();
sortTest.BubbleSort(arr);
}
結(jié)果:

到此這篇關(guān)于Java排序算法之冒泡排序的原理及優(yōu)化的文章就介紹到這了,更多相關(guān)Java冒泡排序的原理及優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中連接Mongodb進(jìn)行增刪改查的操作詳解
MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù),由C++語(yǔ)言編寫,旨在為WEB應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲(chǔ)解決方案,本文給大家介紹了Java中連接Mongodb進(jìn)行操作,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-06-06
SpringBoot整合easyExcel實(shí)現(xiàn)CSV格式文件的導(dǎo)入導(dǎo)出
這篇文章主要為大家詳細(xì)介紹了SpringBoot整合easyExcel實(shí)現(xiàn)CSV格式文件的導(dǎo)入導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以參考下2024-02-02
ScrollView中嵌入ListView只顯示一條的解決辦法
在ScrollView添加一個(gè)ListView會(huì)導(dǎo)致listview控件顯示不全,通常只會(huì)顯示一條,究竟是什么原因呢?下面腳本之家小編給大家介紹ScrollView中嵌入ListView只顯示一條的解決辦法,感興趣的朋友一起學(xué)習(xí)吧2016-05-05
JAVA SpringBoot統(tǒng)一日志處理原理詳解
這篇文章主要介紹了SpringBoot的統(tǒng)一日志處理原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-09-09
java利用冒泡排序?qū)?shù)組進(jìn)行排序
這篇文章主要介紹了java利用冒泡排序?qū)?shù)組進(jìn)行排序的方法,實(shí)例分析了冒泡排序的概念與java實(shí)現(xiàn)方法,以及java操作數(shù)組的相關(guān)技巧,需要的朋友可以參考下2015-05-05
SpringBoot實(shí)現(xiàn)接口的各種參數(shù)校驗(yàn)的示例
本文主要介紹了SpringBoot實(shí)現(xiàn)接口的各種參數(shù)校驗(yàn)的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Springboot如何基于assembly服務(wù)化實(shí)現(xiàn)打包
這篇文章主要介紹了Springboot如何基于assembly服務(wù)化實(shí)現(xiàn)打包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06

