Java实现基数排序及其推导过程 Radix Sort
生活随笔
收集整理的這篇文章主要介紹了
Java实现基数排序及其推导过程 Radix Sort
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文帶來八大排序算法之基數排序。
基數排序(radix sort)屬于“分配式排序”(distribution sort),又稱“桶子法”(bucket sort),它是通過鍵值的各個位的值,將要排序的元素分配至某些"桶“中,從而達到排序的作用?;鶖蹬判蚴切矢叩姆€定性的排序算法?;鶖蹬判蚴峭芭判虻臄U展。
基數排序基本思想:
將所有待比較的數值統一為同樣的數位長度,數位較短的數前面補零。然后,從最低位開始,依次進行一次排序,這樣從最低位排序一直到最高位排序完成以后,數位就變成一個有序序列。見下圖(以數組{53, 3, 542, 748, 14, 214}進行升序排序,共分三大步):
?
推導過程代碼如下:
//基數排序推導public static void radixSort2(int[] arr){//推導過程://定義一個二維數組,表示10個桶,每個桶表示一個一維數組//說明://1.二維數組包含10個一維數組//2.為了防止在放入數的時候,數據溢出,則每個一維數組(桶),大小定為arr.length//3.很明顯,基數排序是使用空間換時間的經典算法int[][] bucket = new int[10][arr.length];//為了記錄每個桶中,實際存放了多少個數據,我們定義一個一維數組來記錄各個桶每次放入的數據個數//可以這么理解: bucketElementCounts[0] ,記錄的是 bucket[0]桶中放入數據的個數int[] bucketElementCounts = new int[10];//第1輪(針對每個元素的個位數進行排序處理)for(int j=0; j<arr.length; j++){//得到每個元素的個位數int digitOfElement = arr[j] % 10;//放入到對應的桶中bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];bucketElementCounts[digitOfElement]++ ;}//按照這個桶的順序(一維數組的下標依次取出數據,放入原來的數組)int index = 0;//遍歷每一桶,并將桶中的數據放入到原來的數組for(int k=0; k<bucket.length; k++){//如果桶中有數據,我們才放入到原數組中if(bucketElementCounts[k] != 0){//循環bucket中第k個桶(即第k個一維數組),放入到數組中for(int l=0; l<bucketElementCounts[k]; l++){//取出元素放入到arr數組中arr[index++] = bucket[k][l];}}//第1輪處理后,每個桶中的數據復制到原始數組后, 需要將每個bucketElementCounts[k] = 0bucketElementCounts[k] = 0;}System.out.println("第1輪,對個位的排序處理 arr = " + Arrays.toString(arr));/*******************************************************************************///第2輪(針對每個元素的十位數進行排序處理)for(int j=0; j<arr.length; j++){//得到每個元素的十位數int digitOfElement = arr[j] / 10 % 10;//放入到對應的桶中bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];bucketElementCounts[digitOfElement]++ ;}//按照這個桶的順序(一維數組的下標依次取出數據,放入原來的數組)index = 0;//遍歷每一桶,并將桶中的數據放入到原來的數組for(int k=0; k<bucket.length; k++){//如果桶中有數據,我們才放入到原數組中if(bucketElementCounts[k] != 0){//循環bucket中第k個桶(即第k個一維數組),放入到數組中for(int l=0; l<bucketElementCounts[k]; l++){//取出元素放入到arr數組中arr[index++] = bucket[k][l];}}bucketElementCounts[k] = 0;}System.out.println("第2輪,對十位的排序處理 arr = " + Arrays.toString(arr));//第3輪(針對每個元素的百位數進行排序處理)for(int j=0; j<arr.length; j++){//得到每個元素的百位數int digitOfElement = arr[j] / 100 % 10;//放入到對應的桶中bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];bucketElementCounts[digitOfElement]++ ;}//按照這個桶的順序(一維數組的下標依次取出數據,放入原來的數組)index = 0;//遍歷每一桶,并將桶中的數據放入到原來的數組for(int k=0; k<bucket.length; k++){//如果桶中有數據,我們才放入到原數組中if(bucketElementCounts[k] != 0){//循環bucket中第k個桶(即第k個一維數組),放入到數組中for(int l=0; l<bucketElementCounts[k]; l++){//取出元素放入到arr數組中arr[index++] = bucket[k][l];}}bucketElementCounts[k] = 0;}System.out.println("第3輪,對百位的排序處理 arr = " + Arrays.toString(arr));}實現代碼:
import java.util.Arrays;public class RadixSort {public static void main(String[] args){int[] arr = {53, 3, 542, 748, 14, 214};radixSort(arr);}public static void radixSort(int[] arr){//根據radixSort2()推導過程//1.得到數組中最大的數的位數int max = arr[0]; //假設第一個數就是最大的數;for(int i=1; i<arr.length; i++){if(arr[i] > max){max = arr[i];}}//得到最大數是幾位數int maxLength = (max + "").length();//定義一個二維數組,表示10個桶,每個桶表示一個一維數組//說明://1.二維數組包含10個一維數組//2.為了防止在放入數的時候,數據溢出,則每個一維數組(桶),大小定為arr.length//3.很明顯,基數排序是使用空間換時間的經典算法int[][] bucket = new int[10][arr.length];//為了記錄每個桶中,實際存放了多少個數據,我們定義一個一維數組來記錄各個桶每次放入的數據個數//可以這么理解: bucketElementCounts[0] ,記錄的是 bucket[0]桶中放入數據的個數int[] bucketElementCounts = new int[10];//使用循環for(int i=0, n=1; i<maxLength; i++, n*=10){//第一次是個位,第二次是十位,以此類推for(int j=0; j<arr.length; j++){//得到每個元素對應位的值int digitOfElement = arr[j] / n % 10;//放入到對應的桶中bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];bucketElementCounts[digitOfElement]++ ;}//按照這個桶的順序(一維數組的下標依次取出數據,放入原來的數組)int index = 0;//遍歷每一桶,并將桶中的數據放入到原來的數組for(int k=0; k<bucket.length; k++){//如果桶中有數據,我們才放入到原數組中if(bucketElementCounts[k] != 0){//循環bucket中第k個桶(即第k個一維數組),放入到數組中for(int l=0; l<bucketElementCounts[k]; l++){//取出元素放入到arr數組中arr[index++] = bucket[k][l];}}//第i+1輪處理后,每個桶中的數據復制到原始數組后, 需要將每個bucketElementCounts[k] = 0bucketElementCounts[k] = 0;}System.out.println("第"+(i+1)+"輪, arr = " + Arrays.toString(arr));}}}基數排序說明:
1.基數排序是對桶排序的擴展,速度很快;
2.基數排序是經典的“空間換時間”的方式,占用內存很大,當對海量數據排序時,容易造成OutOfMemoryError;
3.基數排序是穩定的。(假定在待排序的記錄序列中,存在多個具有相同關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,r[i] = r[j] 且 r[i]在r[j] 之前,而在排序后的序列中,r[i]仍在r[j] 之前,則稱這種算法是穩定的,否則成為不穩定的);
4.有負數的數組,我們一般不使用基數排序。
總結
以上是生活随笔為你收集整理的Java实现基数排序及其推导过程 Radix Sort的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现归并排序 Merge Sor
- 下一篇: Java实现二分查找及其优化