自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基數(shù)排序的1個小技巧,2種排序方式,3種排序算法

開發(fā) 前端 算法
基數(shù)排序是非比較型整數(shù)排序算法,其原理是將整數(shù)按位分割進行排序?;鶖?shù)排序適用于大范圍數(shù)據(jù)排序,打破了計數(shù)排序的限制。由于整數(shù)也可以表達字符串(比如名字或日期)和特定格式的浮點數(shù),所以基數(shù)排序也不是只能使用于整數(shù)。

[[421174]]

基數(shù)排序

概念

基數(shù)排序是非比較型整數(shù)排序算法,其原理是將整數(shù)按位分割進行排序?;鶖?shù)排序適用于大范圍數(shù)據(jù)排序,打破了計數(shù)排序的限制。由于整數(shù)也可以表達字符串(比如名字或日期)和特定格式的浮點數(shù),所以基數(shù)排序也不是只能使用于整數(shù)。

2種排序方式

最低位優(yōu)先法(LSD):從最低位向最高位依次按位進行排序。

最高位優(yōu)先法(MSD):從最高位向最低位依次按位進行排序。

按位分割小技巧

arr[i] / digit % 10,其中digit為10^n。

LSD排序算法實現(xiàn)

算法思想

按位進行計數(shù)排序

算法實現(xiàn)代碼

  1. /** 
  2.      * 按位進行計數(shù)排序 
  3.      * @param arr 
  4.      * @param divid 
  5.      * @return 
  6.      */ 
  7. private static int[] countingSort(int[] arr, int divid){ 
  8.  
  9.     int[] bucket = new int[10]; 
  10.     for (int i = 0; i < arr.length; i++) { 
  11.         bucket[arr[i] / divid % 10]++; 
  12.     } 
  13.  
  14.     for (int i = 1; i < bucket.length; i++) { 
  15.         bucket[i] = bucket[i-1] + bucket[i]; 
  16.     } 
  17.  
  18.     int[] sortArr = new int[arr.length]; 
  19.     for (int i = arr.length - 1; i >= 0; i--){ 
  20.         int position = bucket[arr[i] / divid % 10]; 
  21.         sortArr[position - 1] = arr[i]; 
  22.         bucket[arr[i] / divid % 10]--; 
  23.     } 
  24.     return sortArr; 
  25.  
  26. public static int[] radixSort(int[] arr) { 
  27.     // 查找數(shù)組最大值 
  28.     int max = arr[0]; 
  29.     for (int i = 0; i < arr.length; i++) { 
  30.         max = Math.max(arr[i], max); 
  31.     } 
  32.     // 按位排序 
  33.     int digit = 1; 
  34.     for (int i = 1; i < max; digit*=10, i = digit) { 
  35.         arr = countingSort(arr, digit); 
  36.     } 
  37.     return arr; 

排序驗證:

  1. public static void main(String[] args) { 
  2.      int[] arr = {999,1000,1001,1000,999,1005}; 
  3.      System.out.println("排序前:" + JSON.toJSONString(arr)); 
  4.      int[] sortArr = radixSort(arr); 
  5.      System.out.println("排序后:" + JSON.toJSONString(sortArr)); 
  6.  } 

排序前:[999,1000,1001,1000,999,1005] 排序后:[999,999,1000,1000,1001,1005]

MSD排序算法實現(xiàn)

算法思想

從最高位開始,按位分組,當(dāng)組內(nèi)元素個數(shù)>1時,遞歸下一位分組,一直分到個位結(jié)束;收集元素個數(shù)=1的。

算法步驟

  • 查詢最大值,獲取最高位的基數(shù)。Math.pow(10, digit - 1)
  • 按位分組,存入桶內(nèi)。groupBucket[position][groupCounter[position]] =arr[i];
  • 組內(nèi)元素數(shù)量>1,下一位遞歸分組。if (groupBucket[i] > 1) {int[] tmp = msdSort(copyArr, radix / 10);}
  • 組內(nèi)元素數(shù)量=1,收集元素。sortArr[index++] = groupBucket[i][0];

比如,對數(shù)組[333,1002,1001,1000,333,1003,2000]進行排序,操作步驟如下:

算法實現(xiàn)代碼

  1. public static int[] sort(int[] arr){ 
  2.  
  3.     int max = arr[0]; 
  4.     for (int i = 0; i < arr.length; i++) { 
  5.         // 獲取最大值 
  6.         max = Math.max(arr[i], max); 
  7.     } 
  8.  
  9.     // 獲取最大值的位數(shù) 
  10.     int digit = getDataDigit(max); 
  11.     // 計算最大值的基數(shù) 
  12.     int radix = new Double(Math.pow(10, digit - 1)).intValue(); 
  13.     // msd基數(shù)排序 
  14.     return msdSort(arr, radix); 
  15.  
  16. /** 
  17.      * MSD 基數(shù)排序 
  18.      * @param arr 
  19.      * @param radix 
  20.      * @return 
  21.      */ 
  22. public static int[] msdSort(int[] arr, int radix){ 
  23.  
  24.     // 遞歸分組到個位,退出 
  25.     if (radix <= 0) { 
  26.         return arr; 
  27.     } 
  28.  
  29.     // 分組計數(shù)器 
  30.     int[] groupCounter = new int[10]; 
  31.     // 分組桶 
  32.     int[][] groupBucket = new int[10][arr.length]; 
  33.     // 遍歷待排序數(shù)組,按位分組 
  34.     for (int i = 0; i < arr.length; i++) { 
  35.         // 計算分組桶位置 
  36.         int position = arr[i] / radix % 10; 
  37.         // 將元素存入分組 
  38.         groupBucket[position][groupCounter[position]] = arr[i]; 
  39.         // 當(dāng)前分組計數(shù)加1 
  40.         groupCounter[position]++; 
  41.     } 
  42.  
  43.     int index = 0; 
  44.     int[] sortArr = new int[arr.length]; 
  45.  
  46.     // 遍歷分組計數(shù)器 
  47.     for (int i = 0; i < groupCounter.length; i++) { 
  48.         // 組內(nèi)元素數(shù)量>1,遞歸分組 
  49.         if (groupCounter[i] > 1) { 
  50.             int[] copyArr = Arrays.copyOf(groupBucket[i], groupCounter[i]); 
  51.             // 遞歸分組 
  52.             int[] tmp = msdSort(copyArr, radix / 10); 
  53.             // 收集遞歸分組后的元素 
  54.             for (int j = 0; j < tmp.length; j++) { 
  55.                 sortArr[index++] = tmp[j]; 
  56.             } 
  57.         } else if (groupCounter[i] == 1) { 
  58.             // 收集組內(nèi)元素數(shù)量=1的元素 
  59.             sortArr[index++] = groupBucket[i][0]; 
  60.         } 
  61.     } 
  62.  
  63.     return sortArr; 
  64.  
  65. /** 
  66.      * 獲取數(shù)據(jù)的位數(shù) 
  67.      * @param data 
  68.      * @return 
  69.      */ 
  70. public static int getDataDigit(int data) { 
  71.     //        int index = 0; 
  72.     //        int digit = 1; 
  73.     //        while (data / digit >0) { 
  74.     //            digit *= 10; 
  75.     //            index++; 
  76.     //        } 
  77.     //        return index
  78.  
  79.     return String.valueOf(data).length(); 

驗證排序結(jié)果:

  1. public static void main(String[] args) { 
  2.     int[] arr = {333,1002,1001,1000,333,1003,2000}; 
  3.     System.out.println("排序前:" + JSON.toJSONString(arr)); 
  4.     int[] sortArr = sort(arr); 
  5.     System.out.println("排序后:" + JSON.toJSONString(sortArr)); 

排序前:[333,1002,1001,1000,333,1003,2000] 排序后:[333,333,1000,1001,1002,1003,2000]

三向切分字符快速排序

算法思想

按位將字符串切分為三個區(qū)間,小于v區(qū)間:[lo,lt-1],等于v區(qū)間:[lt,gt],大于v區(qū)間: [gt+1,hi],依次遞歸三個區(qū)間。

算法步驟

  • 定義小于v區(qū)間的看門狗lt,大于v區(qū)間的看門狗gt。
  • 按位比較劃分三個區(qū)間。
  • 遞歸三個區(qū)間。

算法實現(xiàn)代碼

  1. /** 
  2.      * 按位將字符串切分為三個區(qū)間 
  3.      * 1. 小于v區(qū)間:[lo,lt] 
  4.      * 2. 等于v區(qū)間:[lt,gt] 
  5.      * 3. 大于v區(qū)間: [gt+1,hi] 
  6.      * @param arr 
  7.      * @param lo 
  8.      * @param hi 
  9.      * @param d 
  10.      */ 
  11. public static void sortStr(String[] arr, int lo, int hi, int d){ 
  12.     if (hi <= lo) { 
  13.         return
  14.     } 
  15.     // 定義小于v的看門lt, 大于v的看門gt 
  16.     int lt = lo, gt = hi, i = lo + 1, v = charAt(arr[lo],d); 
  17.     while (i <= gt){ 
  18.         int t = charAt(arr[i], d); 
  19.         if (t < v) { 
  20.             exch(arr, i++, lt++); 
  21.         } else if (t > v) { 
  22.             exch(arr, i, gt--); 
  23.         } else { 
  24.             i++; 
  25.         } 
  26.     } 
  27.  
  28.     // 遞歸小于v的區(qū)間 
  29.     sortStr(arr, lo, lt - 1, d); 
  30.     // 遞歸等于v的區(qū)間 
  31.     if (v >= 0) { 
  32.         sortStr(arr, lt, gt, d + 1); 
  33.     } 
  34.     // 遞歸大于v的區(qū)間 
  35.     sortStr(arr, gt + 1, hi, d); 
  36. private static int charAt(String s, int d) { 
  37.     if (d < s.length()) { 
  38.         return s.charAt(d); 
  39.     } 
  40.     return -1; 
  41. public static void exch(String[] arr, int sourceIdx, int targetIdx) { 
  42.     String tmp = arr[sourceIdx]; 
  43.     arr[sourceIdx] = arr[targetIdx]; 
  44.     arr[targetIdx] = tmp; 
  45. 結(jié)果驗證: 
  46.  
  47.  public static void main(String[] args) { 
  48.      String[] a = new String[]{"by","air","she","shell","the","okay","bump","shirt","shells","sh","the","shells","the"}; 
  49.      System.out.println("排序前:" + JSON.toJSONString(a)); 
  50.      sortStr(a, 0, a.length - 1, 0); 
  51.      System.out.println("排序后:" + JSON.toJSONString(a)); 
  52.  } 

排序前:["by","air","she","shell","the","okay","bump","shirt","shells","sh","the","shells","the"] 排序后:["air","bump","by","okay","sh","she","shell","shells","shells","shirt","the","the","the"]

三種排序算法對比

算法

是否穩(wěn)定

原地排序

運行時間

額外空間

優(yōu)點領(lǐng)域

低位優(yōu)先的字符串排序(LSD)

O(n x k)

O(n + k)

較短的定長字符串

高位優(yōu)先的字符串排序(MSD)

O(n x k)

O(N+kk)

隨機字符串

三向字符串快速排序

O(NlogN)

W+logN

通用排序算法,特別適用于含有較長公共前綴的字符串?dāng)?shù)組

總結(jié)

基數(shù)排序是穩(wěn)定、非比較排序,適合用于大數(shù)據(jù)范圍的。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2011-04-20 16:05:15

基數(shù)排序

2021-04-22 10:07:45

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-06-24 17:55:40

Python 開發(fā)編程語言

2009-08-26 18:14:11

C#排序算法

2015-03-19 15:13:20

PHP基本排序算法代碼實現(xiàn)

2014-05-30 09:08:42

排序算法測試

2009-09-08 17:20:01

C#排序算法

2024-02-26 00:06:00

排序?qū)W習(xí)算法斯奇拉姆

2023-10-05 09:01:05

插入排序對象序列log2i

2011-04-20 14:07:37

冒泡排序

2011-04-20 13:56:08

選擇排序

2011-04-20 14:19:00

希爾排序

2018-11-01 13:49:23

桶排序排序面試

2023-03-06 08:10:52

數(shù)據(jù)結(jié)構(gòu)算法數(shù)據(jù)

2011-04-20 15:06:44

堆排序

2011-04-20 15:20:03

快速排序

2021-01-19 07:02:26

算法數(shù)據(jù)結(jié)構(gòu)堆排序

2021-02-01 10:17:14

編程C語言計算機

2022-03-12 20:12:08

希爾排序數(shù)組插入排序

2011-04-20 14:29:07

歸并排序
點贊
收藏

51CTO技術(shù)棧公眾號