演算法學習第十日之基數排序(桶排序)
阿新 • • 發佈:2021-01-20
目錄
基數排序
介紹
基本思想
動畫示意
程式碼:
package com.atguigu.sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class RadixSort { public static void main(String[] args) { int arr[] = { 53, 3, 542, 748, 14, 214}; // 80000000 * 11 * 4 / 1024 / 1024 / 1024 =3.3G // int[] arr = new int[8000000]; // for (int i = 0; i < 8000000; i++) { // arr[i] = (int) (Math.random() * 8000000); // 生成一個[0, 8000000) 數 // } System.out.println("排序前"); Date data1 = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date1Str = simpleDateFormat.format(data1); System.out.println("排序前的時間是=" + date1Str); radixSort(arr); Date data2 = new Date(); String date2Str = simpleDateFormat.format(data2); System.out.println("排序前的時間是=" + date2Str); System.out.println("基數排序後 " + Arrays.toString(arr)); } //基數排序方法 public static void radixSort(int[] arr) { //根據前面的推導過程,我們可以得到最終的基數排序程式碼 //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 < bucketElementCounts.length; k++) { //如果桶中,有資料,我們才放入到原陣列 if(bucketElementCounts[k] != 0) { //迴圈該桶即第k個桶(即第k個一維陣列), 放入 for(int l = 0; l < bucketElementCounts[k]; l++) { //取出元素放入到arr arr[index++] = bucket[k][l]; } } //第i+1輪處理後,需要將每個 bucketElementCounts[k] = 0 !!!! bucketElementCounts[k] = 0; } //System.out.println("第"+(i+1)+"輪,對個位的排序處理 arr =" + Arrays.toString(arr)); } /* //第1輪(針對每個元素的個位進行排序處理) for(int j = 0; j < arr.length; j++) { //取出每個元素的個位的值 int digitOfElement = arr[j] / 1 % 10; //放入到對應的桶中 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; bucketElementCounts[digitOfElement]++; } //按照這個桶的順序(一維陣列的下標依次取出資料,放入原來陣列) int index = 0; //遍歷每一桶,並將桶中是資料,放入到原陣列 for(int k = 0; k < bucketElementCounts.length; k++) { //如果桶中,有資料,我們才放入到原陣列 if(bucketElementCounts[k] != 0) { //迴圈該桶即第k個桶(即第k個一維陣列), 放入 for(int l = 0; l < bucketElementCounts[k]; l++) { //取出元素放入到arr arr[index++] = bucket[k][l]; } } //第l輪處理後,需要將每個 bucketElementCounts[k] = 0 !!!! bucketElementCounts[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; //748 / 10 => 74 % 10 => 4 // 放入到對應的桶中 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; bucketElementCounts[digitOfElement]++; } // 按照這個桶的順序(一維陣列的下標依次取出資料,放入原來陣列) index = 0; // 遍歷每一桶,並將桶中是資料,放入到原陣列 for (int k = 0; k < bucketElementCounts.length; k++) { // 如果桶中,有資料,我們才放入到原陣列 if (bucketElementCounts[k] != 0) { // 迴圈該桶即第k個桶(即第k個一維陣列), 放入 for (int l = 0; l < bucketElementCounts[k]; l++) { // 取出元素放入到arr arr[index++] = bucket[k][l]; } } //第2輪處理後,需要將每個 bucketElementCounts[k] = 0 !!!! 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; // 748 / 100 => 7 % 10 = 7 // 放入到對應的桶中 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; bucketElementCounts[digitOfElement]++; } // 按照這個桶的順序(一維陣列的下標依次取出資料,放入原來陣列) index = 0; // 遍歷每一桶,並將桶中是資料,放入到原陣列 for (int k = 0; k < bucketElementCounts.length; k++) { // 如果桶中,有資料,我們才放入到原陣列 if (bucketElementCounts[k] != 0) { // 迴圈該桶即第k個桶(即第k個一維陣列), 放入 for (int l = 0; l < bucketElementCounts[k]; l++) { // 取出元素放入到arr arr[index++] = bucket[k][l]; } } //第3輪處理後,需要將每個 bucketElementCounts[k] = 0 !!!! bucketElementCounts[k] = 0; } System.out.println("第3輪,對個位的排序處理 arr =" + Arrays.toString(arr)); */ } }