时间排序_数据结构——基数排序(经典以空间换时间案例)

基数排序(经典以空间换取时间案例)

一:基数排序介绍:

  • 基数排序(radix sort)属于“分配式排序”(distribution sort),又称为“桶子法”(bucket sort)或 bin sort,顾名思义,它是通过键值的各个为的值,将要进行排序的元素分配到某些“桶”中,以达到排序的目的。

  • 基数排序属于稳定性的排序,基数排序的是效率高的稳定性排序法

  • 基数排序是桶排序的扩展

  • 基数排序是1887年赫尔曼·何乐礼发明的,它是这样实现的:将整数按照位数切割成不同的数字,然后按照每个位数分别比较。

二:基数排序基本思想:

  • 将所有等待比较的数值统一为同样的位数长度,位数较短的数前面补零。然后,从最低为开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成之后,数列就变成了一个有序序列。图文展示:假设有数组[53,3,542,748,14,214]

  • f8a15d53893486a83c8e4d92f2080cfa.pngbcb4a4afe39bcabc833da94e69ca07a2.png661113ee2dbf6cf2223fdbd8bf93cb56.png

三:代码

实现思路:

1、首先确定会有几轮入桶和出桶的趟数,趟数是看待排序的数据最大有几位,例如最大数十个三位数,那么总共就会有三轮。2、一共是个桶,每个桶的大小应该是数组是的长度,最极端的假设是数组中的所有数据都是一样的,那么在进行桶排序的时候,就只会进入一个桶,从而造成有很多空间浪费掉,但现实情况并不会发生,所以基数排序是空间换取时间的经典算法。另外还要有一个数组,数组长度是桶的数量,即数组下标用来表示哪个桶,下标对应的数据表示该桶中有几个数据。3、接下来就是将数据按照个位,十位,百位。。。的数据的大小分别放入对应的桶中。在放完之后,再从桶中取出数据。注意一点是:每次取出数据之后,都要将记录桶中有多少数据的那个数组中对应的数据置为0。

 package 排序算法;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/*
基数排序
*/
public class RadixSort {
public static void main(String[] args) {
// int[] array = {53,3,542,748,14,214};
int[] array = new int[80000];
for (int i = 0; i < array.length; i++) {
array[i] = (int)(Math.random()*80000);
}

Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(date);
System.out.println(format);

radixSort(array);

Date date1 = new Date();
String format1 = simpleDateFormat.format(date1);
System.out.println(format1);

}

//算法
public static void radixSort(int[] array){

//先获得进行操作的次数,次数跟数据的位数相关,其中的数据是三位数,那么总操作次数就是3次
int max = array[0];
for (int i = 0; i < array.length; i++) {
if (array[i]>max){
max = array[i];
}
}
//获取次数
int maxLength = (max+"").length();

//总共十个桶,每个桶的大小应该是数组长度的大小
int[][] bucket = new int[10][array.length];

//在定义一个桶,下标表示是第几个桶,对应数据就是桶中存放多少数据
int[] bucketElementCounts = new int[10];


for (int i = 0 , n = 1; i < maxLength; i++ , n*=10) {

//将数据全部存放到桶中。
for (int j = 0; j < array.length; j++) {
//获取数据
int digitOfElement = array[j] / n % 10;
//将数据存放到数组中
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = array[j];
bucketElementCounts[digitOfElement] ++;
}

//将数据从桶中取出
int index = 0;

for (int k = 0; k < bucketElementCounts.length; k++) {
if (bucketElementCounts[k]!=0){
for (int d = 0;d < bucketElementCounts[k];d++){
array[index] = bucket[k][d];
index ++;
}
bucketElementCounts[k] = 0;
}
}
}
System.out.println(Arrays.toString(array));

}


四:对基数排序的说明

  1. 基数排序是对传统桶排序的扩展,速度很快。

  2. 基数排序是经典的以空间换取时间的方式。占用内存会很大,当面对海量数据进行排序的时候,容易造成OutOfMemeryError。

  3. 基数排序是稳定的,所谓稳定的就是在待排序的记录中,存在多个具有相同关键字的记录,若经过排序,这些记录的相对次序是不变的。即在原序列中r[i] = r[j],且r[i]在r[j]之前,而在排序之后,r[i]仍在r[j]之前,这种排序算法就是稳定的。

  4. 基数排序并不能用来进行有负数的排序。当然也可以支持有负数的排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值