JAVA十大排序算法之基數(shù)排序詳解
基數(shù)排序
常見的數(shù)據(jù)元素一般是由若干位組成的,比如字符串由若干字符組成,整數(shù)由若干位0~9數(shù)字組成。
基數(shù)排序按照從右往左的順序,依次將每一位都當(dāng)做一次關(guān)鍵字,然后按照該關(guān)鍵字對(duì)數(shù)組排序,同時(shí)每一輪排序都基于上輪排序后的結(jié)果;當(dāng)我們將所有的位排序后,整個(gè)數(shù)組就達(dá)到有序狀態(tài)?;鶖?shù)排序不是基于比較的算法。
基數(shù)是什么意思?對(duì)于十進(jìn)制整數(shù),每一位都只可能是0~9中的某一個(gè),總共10種可能。那10就是它的基,同理二進(jìn)制數(shù)字的基為2;對(duì)于字符串,如果它使用的是8位的擴(kuò)展ASCII字符集,那么它的基就是256。
基數(shù)排序有兩種方法:
- MSD 從高位開始進(jìn)行排序
- LSD 從低位開始進(jìn)行排序
對(duì)于大小范圍為0~9的數(shù)的組合(若是兩位數(shù),就是個(gè)位數(shù)和十位數(shù)的組合),于是可以準(zhǔn)備十個(gè)桶,然后放到對(duì)應(yīng)的桶里,然后再把桶里的數(shù)按照0號(hào)桶到9號(hào)桶的順序取出來(lái)即可。
代碼實(shí)現(xiàn)
public class RadixSort { public static final int[] ARRAY = {82, 50, 21, 5, 66, 48, 43, 79, 14, 37, 25}; public static int[] sort(int[] array) { if (array.length < 2) return array; //根據(jù)最大值算出位數(shù) int max = array[0]; for (int temp : array) { if (temp > max) { max = temp; } } //算出位數(shù)digit int maxDigit = 0; while (max != 0) { max /= 10; maxDigit++; } //創(chuàng)建桶并初始化 ArrayList<ArrayList<Integer>> bucket = new ArrayList<>(); for (int i = 0; i < 10; i++) { bucket.add(new ArrayList<>()); } //按照從右往左的順序,依次將每一位都當(dāng)做一次關(guān)鍵字,然后按照該關(guān)鍵字對(duì)數(shù)組排序,每一輪排序都基于上輪排序后的結(jié)果 int mold = 10;//取模運(yùn)算 int div = 1;//獲取對(duì)應(yīng)位數(shù)的值 for (int i = 0; i < maxDigit; i++, mold *= 10, div *= 10) { for (int j = 0; j < array.length; j++) { //獲取個(gè)位/十位/百位...... int num = (array[j] % mold) / div; //把數(shù)據(jù)放入到對(duì)應(yīng)的桶里 bucket.get(num).add(array[j]); } //把桶中的數(shù)據(jù)重新寫回去,并把桶的元素清空,開始第二輪排序 int index = 0; for (int k = 0; k < bucket.size(); k++) { //桶中對(duì)應(yīng)的數(shù)據(jù) ArrayList<Integer> list = bucket.get(k); for (int m = 0; m < list.size(); m++) { array[index++] = list.get(m); } //清除桶 bucket.get(k).clear(); } } return array; } public static void print(int[] array) { for (int i : array) { System.out.print(i + " "); } System.out.println(""); } public static void main(String[] args) { print(ARRAY); System.out.println("============================================"); print(sort(ARRAY)); } }
時(shí)間復(fù)雜度
計(jì)數(shù)排序算法的時(shí)間復(fù)雜度是O(N+M),基數(shù)排序算法執(zhí)行了k次計(jì)數(shù)排序,所以基數(shù)排序算法的時(shí)間復(fù)雜度為O(K(N+M))。
算法穩(wěn)定性
從上面的分析可以看出,相同元素會(huì)按照順序放進(jìn)固定的桶內(nèi),取出的時(shí)候也是按照順序取出來(lái)的,所以基數(shù)排序算法是一種穩(wěn)定的排序算法。
基數(shù)排序 vs 桶排序 vs 計(jì)數(shù)排序
這三種排序算法都利用了桶的概念,但對(duì)桶的使用方法上有明顯差異
- 基數(shù)排序:根據(jù)每一位的關(guān)鍵字來(lái)分配桶
- 桶排序:存儲(chǔ)一定范圍的值
- 計(jì)數(shù)排序:每個(gè)桶只存儲(chǔ)一個(gè)類型值,但是數(shù)量不限
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
淺談String類型如何轉(zhuǎn)換為time類型存進(jìn)數(shù)據(jù)庫(kù)
這篇文章主要介紹了String類型如何轉(zhuǎn)換為time類型存進(jìn)數(shù)據(jù)庫(kù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03java微信開發(fā)API第四步 微信自定義個(gè)性化菜單實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了java微信開發(fā)API第四步,自定義菜單以及個(gè)性化菜單實(shí)現(xiàn) ,感興趣的小伙伴們可以參考一下2016-06-06Spring Cloud Config分布式配置中心使用介紹詳解
分布式配置中心應(yīng)用場(chǎng)景 往往,我們使用配置文件管理?些配置信息,比如application.yml 單體應(yīng)用架構(gòu):配置信息的管理、維護(hù)并不會(huì)顯得特別麻煩,手動(dòng)操作就可以,因?yàn)榫鸵粋€(gè)工程2022-09-09mybatis中映射文件include標(biāo)簽的應(yīng)用
這篇文章主要介紹了mybatis中映射文件include標(biāo)簽的應(yīng)用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java的@Transactional、@Aysnc、事務(wù)同步問題詳解
這篇文章主要介紹了Java的@Transactional、@Aysnc、事務(wù)同步問題詳解,現(xiàn)在我們需要在一個(gè)業(yè)務(wù)方法中插入一個(gè)用戶,這個(gè)業(yè)務(wù)方法我們需要加上事務(wù),然后插入用戶后,我們要異步的方式打印出數(shù)據(jù)庫(kù)中所有存在的用戶,需要的朋友可以參考下2023-11-11基于swagger測(cè)試List類型參數(shù)過程詳解
這篇文章主要介紹了基于swagger測(cè)試List類型參數(shù)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09java使用ffmpeg命令來(lái)實(shí)現(xiàn)視頻編碼轉(zhuǎn)換的示例
本文主要介紹了java使用ffmpeg命令來(lái)實(shí)現(xiàn)視頻編碼轉(zhuǎn)換的示例,可以通過調(diào)用系統(tǒng)命令來(lái)執(zhí)行FFmpeg命令,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07