Java桶排序之基数排序详解

基数排序也是桶排序的一种,也是跟样本数据强相关的,且基数排序要求样本数据是非负的十进制数,如果有小数或者负数,那么代码将要大量重写!这就是不基于比较的排序的弊端。一般来说,我们认为基数排序时间复杂度为O(N)。但事实上,如果数据量很大很大,它的时间复杂度是O(N*log10(Max))(底数是10)。

基数排序算法流程不是很难,但是以下代码实现方式比较骚,所以先放上一张截图,方便查看。

我们知道基数排序的实现流程是需要准备10个队列的,但是经典的实现流程却是利用了一个count数组来模拟了出队列的操作,所以节省了空间。

package com.harrison.class05;
import java.util.Arrays;
// 基数排序也是桶排序的一种,也是跟样本数据强相关的
// 且基数排序要求样本数据是非负的十进制数
// 如果有小数或者负数,那么代码将要大量重写!
// 这就是不基于比较的排序的弊端
// 一般来说,我们认为基数排序时间复杂度为O(N)
// 但事实上,如果数据量很大很大,它的时间复杂度是O(N*log10(Max))(底数是10)
public class Code03_RadixSort {
	public static void radixSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		radixSort(arr, 0, arr.length - 1, maxBits(arr));
	}
	// 求出数组中最大值的位数
	// 比如数组中最大值是100 那么返回3
	public static int maxBits(int[] arr) {
		int max = Integer.MIN_VALUE;
		for (int i = 0; i < arr.length; i++) {
			max = Math.max(max, arr[i]);
		}
		int res = 0;
		while (max != 0) {
			res++;
			max /= 10;
		}
		return res;
	}
	// 此方法配合截图理解!!!
	public static void radixSort(int[] arr, int L, int R, int digit) {
		final int radix = 10;
		int i = 0, j = 0;
		// 原数组有多少个数,准备多少个空间
		int[] help = new int[R - L + 1];
		for (int d = 1; d <= digit; d++) {
			int[] count = new int[radix];
			for (i = L; i <= R; i++) {
				j = getDigits(arr[i], d);
				count[j]++;
			}
			for (i = 1; i < radix; i++) {
				count[i] = count[i] + count[i - 1];
			}
			for (i = R; i >= L; i--) {
				j = getDigits(arr[i], d);
				help[count[j] - 1] = arr[i];
				count[j]--;
			}
			for (i = 0, j = 0; i <= R; i++, j++) {
				arr[i] = help[i];
			}
		}
	}
	public static int getDigits(int x, int d) {
		return ((x / (int) (Math.pow(10, d - 1)))) % 10;
	}
	public static void comparator(int[] arr) {
		Arrays.sort(arr);
	}
	public static int[] generateRandomArray(int maxSize, int maxValue) {
		int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) ((maxValue + 1) * Math.random());
		}
		return arr;
	}
	public static int[] copyArray(int[] arr) {
		if (arr == null) {
			return null;
		}
		int[] res = new int[arr.length];
		for (int i = 0; i < arr.length; i++) {
			res[i] = arr[i];
		}
		return res;
	}
	public static boolean isEqual(int[] arr1, int[] arr2) {
		if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
			return false;
		}
		if (arr1 == null && arr2 == null) {
			return true;
		}
		if (arr1.length != arr2.length) {
			return false;
		}
		for (int i = 0; i < arr1.length; i++) {
			if (arr1[i] != arr2[i]) {
				return false;
			}
		}
		return true;
	}
	public static void printArray(int[] arr) {
		if (arr == null) {
			return;
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}
	public static void main(String[] args) {
		int testTime = 500000;
		int maxSize = 100;
		int maxValue = 100000;
		boolean succeed = true;
		for (int i = 0; i < testTime; i++) {
			int[] arr1 = generateRandomArray(maxSize, maxValue);
			int[] arr2 = copyArray(arr1);
			radixSort(arr1);
			comparator(arr2);
			if (!isEqual(arr1, arr2)) {
				succeed = false;
				printArray(arr1);
				printArray(arr2);
				break;
			}
		}
		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
		int[] arr = generateRandomArray(maxSize, maxValue);
		printArray(arr);
		radixSort(arr);
		printArray(arr);
	}
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • JAVA十大排序算法之基数排序详解

    目录 基数排序 代码实现 时间复杂度 算法稳定性 基数排序 vs 桶排序 vs 计数排序 总结 基数排序 常见的数据元素一般是由若干位组成的,比如字符串由若干字符组成,整数由若干位0~9数字组成. 基数排序按照从右往左的顺序,依次将每一位都当做一次关键字,然后按照该关键字对数组排序,同时每一轮排序都基于上轮排序后的结果:当我们将所有的位排序后,整个数组就达到有序状态.基数排序不是基于比较的算法. 基数是什么意思?对于十进制整数,每一位都只可能是0~9中的某一个,总共10种可能.那10就是它的基,

  • Java关于桶排序的知识点总结

    前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本文从最简单的一个排序算法--桶排序开始,分析桶排序的实现思路,代码实现,性能特点以及适用场景. 0.其他排序算法索引 http://www.jb51.net/article/120879.htm 1.桶排序思想 一个简单例子: 对6个人的英语测试成绩(1~10分)进行排序.假如分数是[6,5,8,8,10,9],用桶排序的思想就是准备10个桶,编号依次为1~10,将成绩放入对应的桶中,例如6分放入6号桶,两个8分放入8号桶...然

  • Java基数排序radix sort原理及用法解析

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

  • java数据结构与算法之桶排序实现方法详解

    本文实例讲述了java数据结构与算法之桶排序实现方法.分享给大家供大家参考,具体如下: 基本思想: 假定输入是由一个随机过程产生的[0, M)区间上均匀分布的实数.将区间[0, M)划分为n个大小相等的子区间(桶),将n个输入元素分配到这些桶中,对桶中元素进行排序,然后依次连接桶输入0 ≤A[1..n] <M辅助数组B[0..n-1]是一指针数组,指向桶(链表).将n个记录分布到各个桶中去.如果有多于一个记录分到同一个桶中,需要进行桶内排序.最后依次把各个桶中的记录列出来记得到有序序列. [桶-

  • 基数排序简介及Java语言实现

    基本思想 基数排序(RadixSort)是在桶排序的基础上发展而来的,两种排序都是分配排序的高级实现.分配排序(DistributiveSort)的基本思想:排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n). 基数排序是一种稳定的排序算法,但有一定的局限性: 1.关键字可分解. 2.记录的关键字位数较少,如果密集更好 3.如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序. 先来看一

  • java 实现计数排序和桶排序实例代码

    java 实现计数排序和桶排序实例代码 目录 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比较排序.在排序的最终结果里,元素之间的次序依赖于它们之间的比较.每个数都必须和其他数进行比较,才能确定自己的位置. 在 冒泡排序 之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²).在 归并排序.快速排序 之类的排序中,问题规模通过分治法消减为logN次,所以时间复杂度平均 O(nlogn) . 比较排序的优势是,适用于各种规模的数据,也不在乎数据的分布

  • Java语言实现基数排序代码分享

    算法思想:依次按个位.十位...来排序,每一个pos都有分配过程和收集过程,array[i][0]记录第i行数据的个数. package sorting; /** * 基数排序 * 平均O(d(n+r)),最好O(d(n+r)),最坏O(d(n+r));空间复杂度O(n+r);稳定;较复杂 * d为位数,r为分配后链表的个数 * @author zeng * */ public class RadixSort { //pos=1表示个位,pos=2表示十位 public static int g

  • JAVA十大排序算法之桶排序详解

    目录 桶排序 代码实现 时间复杂度 算法稳定性 总结 桶排序 桶排序是计数排序的升级,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过函数的某种映射关系,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序),最后将非空桶中的元素逐个放入原序列中. 桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效. 代码实现 1.找出数组中的最大值max和最小值min,可以确定出数组所在范

  • Java桶排序之基数排序详解

    基数排序也是桶排序的一种,也是跟样本数据强相关的,且基数排序要求样本数据是非负的十进制数,如果有小数或者负数,那么代码将要大量重写!这就是不基于比较的排序的弊端.一般来说,我们认为基数排序时间复杂度为O(N).但事实上,如果数据量很大很大,它的时间复杂度是O(N*log10(Max))(底数是10). 基数排序算法流程不是很难,但是以下代码实现方式比较骚,所以先放上一张截图,方便查看. 我们知道基数排序的实现流程是需要准备10个队列的,但是经典的实现流程却是利用了一个count数组来模拟了出队列

  • C/C++语言八大排序算法之桶排序全过程示例详解

    基本思路是将所有数的个位十位百位一直到最大数的最高位一步步装桶,先个位装桶然后出桶,直到最高位入桶出桶完毕. 首先我们要求出一个数组的最大数然后求出他的最大位数 //求最大位数的函数 int getmaxweisu(int* a,int len)// { int max = a[0]; for (int i = 0; i < len; i++) { if (max < a[i]) { max = a[i]; } } int count = 1; while (max/10) { count++

  • java 中基本算法之希尔排序的实例详解

    java 中基本算法之希尔排序的实例详解 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法.该方法因DL.Shell于1959年提出而得名. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差

  • Java使用Collections.sort()排序的示例详解

    Java中Collections.sort()排序详解,通过实例代码给大家讲解,具体代码如下所示: public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("beijing"); list.add("shanghai"); list.add("hangzhou"); Collections.

  • java数组算法例题代码详解(冒泡排序,选择排序,找最大值、最小值,添加、删除元素等)

    数组算法例题 1.数组逆序 第一个和最后一个互换,第二个和倒数第二个互换,就相当于把数组想下图一样,进行对折互换,如果数组个数为奇数,则中间保持不变其余元素互换即可 import java.util.Arrays; class Demo12 { public static void main (String[] args) { int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println(Arrays.toString(arr));

  • Java实现ArrayList排序的方法详解

    目录 简介 法1:JDK8的stream 法2:Comparator#compare() 法3:Comparable#compareTo() 简介 说明 本文用示例介绍Java的ArrayList排序的方法. List排序方法 主要有三种方法(按推荐度排序): JDK8的stream Comparator#compare() Comparable#compareTo() 法1:JDK8的stream 见:一文详解Java中Stream流的使用 法2:Comparator#compare() 需求

  • Java实现自定义Excel数据排序的方法详解

    目录 1.引入jar包 2.自定义排序 通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值.单元格颜色.字体颜色或图标等.在需要自定义排序情况下,我们也可以自行根据排序需要编辑数据排列顺序.本文,将通过Java应用程序来实现如何自定义排序. 1.引入jar包 使用jar包:Spire.Xls.jar version: 12.8.4 导入方法1:手动下载jar到本地,解压,然后找到lib文件夹下的Spire.Xls.jar文件.然后在IDEA中打开“Proje

  • Python 十大经典排序算法实现详解

    目录 关于时间复杂度 关于稳定性 名词解释 1.冒泡排序 (1)算法步骤 (2)动图演示 (3)Python代码 2.选择排序 (1)算法步骤 (2)动图演示 (3)Python代码 3.插入排序 (1)算法步骤 (2)动图演示 (3)Python代码 4.希尔排序 (1)算法步骤 (2)Python代码 5.归并排序 (1)算法步骤 (2)动图演示 (3)Python代码 6.快速排序 (1)算法步骤 (2)动图演示 (3)Python代码 7.堆排序 (1)算法步骤 (2)动图演示 (3)P

  • java TreeMap源码解析详解

    java TreeMap源码解析详解 在介绍TreeMap之前,我们来了解一种数据结构:排序二叉树.相信学过数据结构的同学知道,这种结构的数据存储形式在查找的时候效率非常高. 如图所示,这种数据结构是以二叉树为基础的,所有的左孩子的value值都是小于根结点的value值的,所有右孩子的value值都是大于根结点的.这样做的好处在于:如果需要按照键值查找数据元素,只要比较当前结点的value值即可(小于当前结点value值的,往左走,否则往右走),这种方式,每次可以减少一半的操作,所以效率比较高

随机推荐