排序算法-基数排序

基数排序

基数排序(桶排序)介绍:

 

 

  1. 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或 bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
  2. 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
  3. 基数排序(Radix Sort)是桶排序的扩展
  4. 基数排序是 1887 年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。

基数排序基本思想

 

 

  1. 将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

 

 

  1. 这样说明,比较难理解,下面我们看一个图文解释,理解基数排序的步骤

 

 

基数排序图文说明

将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序

 

 

 

 

 

基数排序代码实现

要求:将数组 {53, 3, 542, 748, 14, 214} 使用基数排序, 进行升序排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package com.xuge.sort;
 
import java.util.Arrays;
 
/**
 * author: yjx
 * Date :2022/5/3022:05
 **/
public class RadixSort {
  public static void main(String[] args) {
    int[] arr = {53, 3, 542, 748, 14, 214};
    redisSort(arr);
  }
 
  public static void redisSort(int[] arr) {
    //1.得到数组中最大的位数
    int max = arr[0];
 
    for(int i=1;i<arr.length;i++){
      if(max<arr[i]){
        max=arr[i];
      }
    }
 
    int maxLength = (max + "").length();
    //2.遍历maxLength轮
    for (int i = 0 ,n=1; i < maxLength; i++,n*=10) {
      //针对每一个位排序
      //1.第一轮排序 针对每个元素各位
      //2.二维数组包含10个一维数组,每个一维数组大小定位arr.length;
      //3.是使用空间换时间的经典算法
      int[][] buceket = new int[10][arr.length];
 
      //为了记录每个桶实际存放的数据个数
      //buceketElementCounts[0]记录第0个桶放入数据个数
      int[] buceketElementCounts = new int[10];
      for (int j = 0; j < arr.length; j++) {
        //取出每个元素的个位数
        int digitOfElement = arr[j] /n%10;
        //放入到对应桶中
        buceket[digitOfElement][buceketElementCounts[digitOfElement]] = arr[j];
        //后移
        buceketElementCounts[digitOfElement]++;
      }
      //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组)
      int index = 0;
      //遍历每一个桶,依次取数据
      for (int k = 0; k < buceketElementCounts.length; k++) {
        //如果桶中有数据,才放入数据
        if (buceketElementCounts[k] != 0) {
          //循环第k个桶,即第k个一维数组
          for (int l = 0; l < buceketElementCounts[k]; l++) {
            //取出元素放入arr[index]中
            arr[index++] = buceket[k][l];
          }
 
        }
        //第一轮处理后,需要将buceketElementCounts置0
        buceketElementCounts[k] = 0;
 
      }
      System.out.println("第"+(i+1)+"轮排序:" + Arrays.toString(arr));
    }
 
 
 
    /*
    //1.第一轮排序 针对每个元素各位
    //2.二维数组包含10个一维数组,每个一维数组大小定位arr.length;
    //3.是使用空间换时间的经典算法
    int [] [] buceket=new int [10][arr.length];
 
    //为了记录每个桶实际存放的数据个数
    //buceketElementCounts[0]记录第0个桶放入数据个数
    int []buceketElementCounts=new int [10];
    for(int j=0;j<arr.length;j++){
      //取出每个元素的个位数
      int digitOfElement=arr[j]%10;
      //放入到对应桶中
      buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j];
      //后移
      buceketElementCounts[digitOfElement]++;
    }
    //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组)
    int index=0;
    //遍历每一个桶,依次取数据
    for(int k=0;k<buceketElementCounts.length;k++){
      //如果桶中有数据,才放入数据
      if(buceketElementCounts[k]!=0){
        //循环第k个桶,即第k个一维数组
        for(int l=0;l<buceketElementCounts[k];l++){
          //取出元素放入arr[index]中
          arr[index++]=buceket[k][l];
        }
 
      }
      //第一轮处理后,需要将buceketElementCounts置0
      buceketElementCounts[k]=0;
 
    }
    System.out.println("第一轮排序:"+ Arrays.toString(arr));
 
 
 
    for(int j=0;j<arr.length;j++){
      //取出每个元素的十位数
      int digitOfElement=arr[j]/10%10;
      //放入到对应桶中
      buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j];
      //后移
      buceketElementCounts[digitOfElement]++;
    }
    //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组)
    index=0;
    //遍历每一个桶,依次取数据
    for(int k=0;k<buceketElementCounts.length;k++){
      //如果桶中有数据,才放入数据
      if(buceketElementCounts[k]!=0){
        //循环第k个桶,即第k个一维数组
        for(int l=0;l<buceketElementCounts[k];l++){
          //取出元素放入arr[index]中
          arr[index++]=buceket[k][l];
        }
 
      }
      //第二轮处理后,需要将buceketElementCounts置0
      buceketElementCounts[k]=0;
    }
    System.out.println("第二轮排序:"+ Arrays.toString(arr));
 
 
 
    for(int j=0;j<arr.length;j++){
      //取出每个元素的十位数
      int digitOfElement=arr[j]/100;
      //放入到对应桶中
      buceket[digitOfElement][buceketElementCounts[digitOfElement]]=arr[j];
      //后移
      buceketElementCounts[digitOfElement]++;
    }
    //按造这个桶的顺序(一维数组下标,依次取出数据,放入原来数组)
    index=0;
    //遍历每一个桶,依次取数据
    for(int k=0;k<buceketElementCounts.length;k++){
      //如果桶中有数据,才放入数据
      if(buceketElementCounts[k]!=0){
        //循环第k个桶,即第k个一维数组
        for(int l=0;l<buceketElementCounts[k];l++){
          //取出元素放入arr[index]中
          arr[index++]=buceket[k][l];
        }
 
      }
      //第二轮处理后,需要将buceketElementCounts置0
      buceketElementCounts[k]=0;
    }
    System.out.println("第三轮排序:"+ Arrays.toString(arr));
    */
 
 
  }
}

 

测试速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
//    int[] arr = {53, 3, 542, 748, 14, 214};
//    redisSort(arr);
    int arr2[] = new int[800000];
    for (int i = 0; i < 800000; i++) {
      arr2[i] = (int) (Math.random() * 800000000);//生成随机数[0,80000000);
    }
    System.out.println("====输出数组=====");
    Date data = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String str = sdf.format(data);
    System.out.println("排序前的时间是:" + str);//23
    redisSort(arr2);
    Date data2 = new Date();
    String str2 = sdf.format(data2);
    System.out.println("排序后的时间是" + str2);//25
  }

  

 

 

 

 

 

posted @   xugeA  阅读(91)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示