手把手教你搞懂冒泡排序和選擇排序
冒泡排序
原理:
從頭(左邊)開始比較每一對相鄰的元素,如果第1個(gè)比第2個(gè)大,就交換它們的位置,執(zhí)行完一輪后,最末尾(最右邊)就是最大的元素。
舉例:
假設(shè)存在數(shù)組nums={6,8,2,9,4},對nums數(shù)組進(jìn)行排序
從左往右開始,拿出兩個(gè)元素進(jìn)行對比,出現(xiàn)兩種情況:
1.左邊元素 <= 右邊元素,不變
2.左邊元素 > 右邊元素,交換他們的位置(這里可以寫成>=嗎?不行,因?yàn)闀?huì)造成排序不穩(wěn)定)
接下來就是新的一輪排序,邏輯跟上圖的流程是一樣的,不同的是會(huì)將最大的元素排除在外,不用進(jìn)行比較。
手撕代碼:
/* 沒有使用過優(yōu)化策略的冒泡排序 */ public class BubbleSort1 { //測試數(shù)據(jù) public static int[] nums = {4,1,7,11,9,55}; //main方法 public static void main(String[] args){ //這個(gè)for循環(huán)每循環(huán)完一次,end--,說明就把最大的元素給選出來了 for (int end = nums.length - 1; end > 0; end--){ for (int begin = 1; begin <= end; begin++){ if(nums[begin] < nums[begin - 1]){ //每當(dāng)發(fā)現(xiàn)左邊的元素大于右邊的元素 //交換元素 int temp = nums[begin]; nums[begin] = nums[begin - 1]; nums[begin - 1] = temp; } } } //打印驗(yàn)證結(jié)果 for(int num : nums){ System.out.print(num+"_"); } } }
時(shí)間復(fù)雜度為O(n^2),
也就是n的平方,不過這是平均時(shí)間復(fù)雜度
存在最好時(shí)間復(fù)雜度O(n)
,那就是數(shù)組本來就有序,也就是說只掃描一遍就行了。
優(yōu)化策略:
由于存在部分有序的情況,例如nums數(shù)組為{8,5,2,10,11,12},也就是說10,11,12都沒有比較的必要了
優(yōu)化代碼:
/* 使用過優(yōu)化策略的冒泡排序 */ public class BubbleSort1 { public static int[] nums = {4,1,7,11,9,55}; public static void main(String[] args){ for (int end = nums.length - 1; end > 0; end--){ int sortIndex = 1; //記錄最后一次交換位置 for (int begin = 1; begin <= end; begin++){ if(nums[begin] < nums[begin - 1]){ int temp = nums[begin - 1]; nums[begin - 1] = nums[begin]; nums[begin] = temp; sortIndex = begin; } end = sortIndex; } } for(int num : nums){ System.out.print(num+"_"); } } }
選擇排序
原理:
從數(shù)組中找到最大的元素,然后與末尾(最右邊)的元素交換位置,執(zhí)行完一輪后,末尾(最右邊)的那個(gè)元素就是最大的元素。
舉例:
假設(shè)存在數(shù)組nums={5,8,1,9,3},對nums數(shù)組進(jìn)行排序,準(zhǔn)備一個(gè)maxIdex代表當(dāng)前最大元素的下標(biāo)
接下來就是新的一輪排序,邏輯跟上圖的流程是一樣的,不同的是會(huì)將最大的元素排除在外,不用進(jìn)行比較。
手撕代碼:
/** * 選擇排序 */ public class SelectionSort { //測試數(shù)據(jù) private static int[] nums = {6,3,2,8,9}; //main方法 public static void main(String[] args){ //這個(gè)for循環(huán)每循環(huán)完一次,end--,說明就把最大的元素給選出來了 for(int end = nums.length - 1; end > 0; end--){ int maxIndex = 0; //假設(shè)下標(biāo)0是數(shù)組中最大元素 for(int begin = 1; begin <= end; begin++){ //從左往右開始比較 if(nums[maxIndex] < nums[begin]){ //發(fā)現(xiàn)存在一個(gè)元素大于假設(shè)最大元素 maxIndex = begin; //更改最大元素索引 } } //最右邊一個(gè)元素和最大值元素交換位置 int temp = nums[maxIndex]; nums[maxIndex] = nums[end]; nums[end] = temp; } //打印結(jié)果 for(int num : nums){ System.out.print(num+"_"); } } }
總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多文章!
相關(guān)文章
Java如何將int型數(shù)組轉(zhuǎn)為String型數(shù)組
這篇文章主要介紹了Java如何將int型數(shù)組轉(zhuǎn)為String型數(shù)組,本文給大家分享具體實(shí)現(xiàn)思路結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-03-03Java實(shí)現(xiàn)異步執(zhí)行的8種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)異步執(zhí)行的8種方式,異步編程不會(huì)阻塞程序的執(zhí)行,它將耗時(shí)的操作提交給后臺(tái)線程或其他執(zhí)行環(huán)境,并立即返回,使得程序可以繼續(xù)執(zhí)行其他任務(wù),需要的朋友可以參考下2023-09-09SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決)
這篇文章主要介紹了SpringBoot項(xiàng)目打包發(fā)布到外部tomcat(出現(xiàn)各種異常的解決),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09java實(shí)現(xiàn)fibonacci數(shù)列學(xué)習(xí)示例分享(斐波那契數(shù)列)
這篇文章主要介紹了fibonacci數(shù)列(斐波那契數(shù)列)示例,大家參考使用吧2014-01-01Springboot使用redisson?+?自定義注解實(shí)現(xiàn)消息的發(fā)布訂閱(解決方案)
Redisson是一個(gè)基于Redis的Java駐留內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory?Data?Grid)和分布式鎖框架,它提供了一系列的分布式Java對象和服務(wù),可以幫助開發(fā)者更方便地使用Redis作為數(shù)據(jù)存儲(chǔ)和分布式鎖的解決方案,感興趣的朋友跟隨小編一起看看吧2024-05-05IDEA全量替換一次性解決舊項(xiàng)目并將所有文件換行符改為LF問題
這篇文章主要介紹了IDEA全量替換一次性解決舊項(xiàng)目并將所有文件換行符改為LF問題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下2019-05-05