排序算法之基数排序、(java分步调试)

基数排序(radix sort)属于分配式排序。基数排序的实现方法分为两种:MSD和LSD。
MSD:最高位优先法(Most Significant Digit First),先比较最高位,最高位分到一个桶中的,再按照第二位进行分桶…,知道分到最后一位,然后再从最小的桶中逐层向上,把元素都拿出来,即完成排序。
LSD:最低位优先法(Least Significant Digit First),先比较最低位,也就是个位,进行分桶,分桶过程中分到一个桶中的数据直接追加到桶中即可,无需排序。然后将所有同种的元素按桶的顺序拿出,重新组成序列,然后比较十位,进行分桶…直到比较到最高位,重新组成序列即可完成排序。
在这里插入图片描述
举例了解如下:

在这里插入图片描述

比较优秀的文章集合:
1、图解+实现 https://blog.csdn.net/lemon_tree12138/article/details/51695211.
2、图解:https://blog.csdn.net/weixin_44537194/article/details/87302788.
3、桶排序的说明https://blog.csdn.net/developer1024/article/details/79770240.
4、基数排序的优化https://blog.csdn.net/yutianzuijin/article/details/22876017.

自己在学习过程中参考编写的如下:留作笔记

编写代码,按照步骤来即可:
注:读取按照下面方式 从上到下,从左到右 进行读取。
【53,3,542,748,14,214】
个位数:将所有数据按照个位数分配到每个桶中。然后依次读取
2: 542
3: 53 3
4: 14 214
8: 748
1 [542, 53, 3, 14, 214, 748]
十位数:将所有数据按照十位数分配到每个桶中。然后依次读取
0: 3
1: 14 214
4: 542 748
5: 53
2 [3, 14, 214, 542, 748, 53]
百位数:将所有数据按照百位数分配到每个桶中。然后依次读取
0: 3 14 53
2: 214
5: 542
7: 748
3 [3, 14, 53, 214, 542, 748]

//打印桶中数据
for(int j = 0 ;j<bucketElementCounts.length;j++) {
			System.out.println(j+":"+Arrays.toString(bucket[j]));
		}

测试程序

public static void main(String[] args) {
		
		int arr[] = {53,3,542,748,14,214};
		radixsort(arr);
		int arr1[] = {53,3,542,748,14,214};
		radixsortBystep(arr1);
		
		int[] arr2 = new int[8000000];
		for(int i =0;i<8000000;i++){
			arr2[i] =(int)( Math.random()*80000000);	//[0-8000000]
		}
		SimpleDateFormat simdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		System.out.println(simdate.format(new Date()));
		radixsort(arr2);
		System.out.println(simdate.format(new Date()));
	}

输出结果:

748
个位[542, 53, 3, 14, 214, 748]
十位[3, 14, 214, 542, 748, 53]
百位[3, 14, 53, 214, 542, 748]
2020-11-16 20:51:40 127
79999993
2020-11-16 20:51:41 033

基数排序的算法实现

	public static void radixsort(int[] arr) {
		//得到元素中最大数的位数
		int max = arr[0];
		for(int i = 1;i<arr.length;i++) {
			if(max < arr[i]) {
				max = arr[i];
			}
		}
		System.out.println(max);
		//得到最大数的位数
		int maxLength = (max + "").length();
		//1、二维数组包含10个一维
		//2、为了防止放置数据的时候溢出,则每一个数组(桶)定义为arr.length
		int[][] bucket = new int[10][arr.length];
		//记录每个桶中有多少有效数据
		int[] bucketElementCounts = new int[10];
		for(int i = 0,n=1;i<maxLength;i++ , n*=10) {
			//1、放在桶中
			for(int j=0 ; j<arr.length ;j++) {
				int digitOfElement = arr[j]/n%10;		
				bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; 	//放到对应桶
				bucketElementCounts[digitOfElement]++;	//有效位数+1
			}
			//2、从桶中取出
			int index = 0;										//按照顺序取出
			for(int k=0;k<bucketElementCounts.length;k++) {		//遍历每一个桶
				if(bucketElementCounts[k]!=0) {					//判断桶中是否有数据
					//如果有数据,循环该桶,并将其放入到arr中
					//System.out.print(k+ ": ");
					for(int l =0 ; l<bucketElementCounts[k];l++) {
						arr[index] = bucket[k][l];			//取出元素放到arr中
						//System.out.print(bucket[k][l]+ " ");
						index++;
					}
					//System.out.print("\n\r");
				}
				//每一轮都要清空
				bucketElementCounts[k] = 0;
			}
			//System.out.println((i+1) + " "+Arrays.toString(arr));
		}	
	}

基数排序算法的分步实现 :

	public static void radixsortBystep(int[] arr) {

		//1、二维数组包含10个一维
		//2、为了防止放置数据的时候溢出,则每一个数组(桶)定义为arr.length
		int[][] bucket = new int[10][arr.length];
		//记录每个桶中有多少有效数据
		int[] bucketElementCounts = new int[10];

		//========第一次,取个位数进行排序========//
		//1、放在桶中
		for(int j=0 ; j<arr.length ;j++) {
			int digitOfElement = arr[j]%10;		//取出个位数
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; 	//放到对应桶
			bucketElementCounts[digitOfElement]++;	//有效位数+1
		}
		//2、从桶中取出
		int index = 0;										//按照顺序取出
		for(int k=0;k<bucketElementCounts.length;k++) {		//遍历每一个桶
			if(bucketElementCounts[k]!=0) {					//判断桶中是否有数据
				//如果有数据,循环该桶,并将其放入到arr中
				for(int l =0 ; l<bucketElementCounts[k];l++) {
					arr[index] = bucket[k][l];			//取出元素放到arr中
					index++;
				}
			}
			//每一轮都要清空
			bucketElementCounts[k] = 0;
			
		}
		System.out.println("个位"+Arrays.toString(arr));
		
		//========第二次,取十位数进行排序========//
		//1、放在桶中
		for(int j=0 ; j<arr.length ;j++) {
			int digitOfElement = arr[j]/10%10;		//取出十位数
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; 	//放到对应桶
			bucketElementCounts[digitOfElement]++;	//有效位数+1
		}
		//2、从桶中取出
		index = 0;										//按照顺序取出
		for(int k=0;k<bucketElementCounts.length;k++) {		//遍历每一个桶
			if(bucketElementCounts[k]!=0) {					//判断桶中是否有数据
				//如果有数据,循环该桶,并将其放入到arr中
				for(int l =0 ; l<bucketElementCounts[k];l++) {
					arr[index] = bucket[k][l];			//取出元素放到arr中
					index++;
				}
			}
			//每一轮都要清空
			bucketElementCounts[k] = 0;
		}
		System.out.println("十位"+Arrays.toString(arr));
		
		//========第三次,取百位数进行排序========//
		//1、放在桶中
		for(int j=0 ; j<arr.length ;j++) {
			int digitOfElement = arr[j]/100%10;		//取出百位数
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; 	//放到对应桶
			bucketElementCounts[digitOfElement]++;	//有效位数+1
		}
		//2、从桶中取出
		index = 0;										//按照顺序取出
		for(int k=0;k<bucketElementCounts.length;k++) {		//遍历每一个桶
			if(bucketElementCounts[k]!=0) {					//判断桶中是否有数据
				//如果有数据,循环该桶,并将其放入到arr中
				for(int l =0 ; l<bucketElementCounts[k];l++) {
					arr[index] = bucket[k][l];			//取出元素放到arr中
					index++;
				}
			}
			//每一轮都要清空
			bucketElementCounts[k] = 0;
		}
		System.out.println("百位"+Arrays.toString(arr));
	}

完。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值