排序算法之基数排序(7)

7.基数排序

7.1实现思路

在这里插入图片描述

7.2具体实现

1.第一轮排序

public class RadixSort {

	public static void main(String[] args) {
		int[] arr = { 5, 234, 34, 48, 135, 3 };
		radixSort(arr);
		System.out.println("第一轮,对个位数的排序处理:" + Arrays.toString(arr));
	}

	public static void radixSort(int[] arr) {
		// 第一轮(针对每个元素的个位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录每次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts = new int[10];

		// 第一轮(针对每个元素的个位进行排序处理)
		for (int j = 0; j < arr.length; j++) {
			// 取出每个元素的个位的值
			int digitOfElement = arr[j] % 10;
			// 放入到对应的桶中
			// 说明:比如说我的第一个数为2,2%10=2
			// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[2],记录的是第2个桶里面元素的个数
			bucket[digitOfElement][bucketElemetnCounts[digitOfElement]] = arr[j];
			bucketElemetnCounts[digitOfElement]++;
		}
		// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
		int index = 0;
		// 遍历每一个桶,并将桶中的数据,放入到原数组
		for (int k = 0; k < bucketElemetnCounts.length; k++) {
			// 如果桶中有数据,我们才取
			if (bucketElemetnCounts[k] != 0) {
				// 遍历该桶
				for (int l = 0; l < bucketElemetnCounts[k]; l++) {
					// 取出元素放入到原数组
					arr[index] = bucket[k][l];
					index++;
				}
			}
		}
	}
}
第一轮,对个位数的排序处理:[3, 234, 34, 5, 135, 48]

2.第二轮排序

public class RadixSort {

	public static void main(String[] args) {
		int[] arr = { 5, 234, 34, 48, 135, 3 };
		radixSort(arr);

	}

	public static void radixSort(int[] arr) {
		// 第一轮(针对每个元素的个位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts = new int[10];

		// 第一轮(针对每个元素的个位进行排序处理)
		for (int j = 0; j < arr.length; j++) {
			// 取出每个元素的个位的值
			int digitOfElement = arr[j] % 10;
			// 放入到对应的桶中
			// 说明:比如说我的第一个数为5234,5%10=0
			// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
			bucket[digitOfElement][bucketElemetnCounts[digitOfElement]] = arr[j];
			bucketElemetnCounts[digitOfElement]++;
		}
		// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
		int index = 0;
		// 遍历每一个桶,并将桶中的数据,放入到原数组
		for (int k = 0; k < bucketElemetnCounts.length; k++) {
			// 如果桶中有数据,我们才取
			if (bucketElemetnCounts[k] != 0) {
				// 遍历该桶
				for (int l = 0; l < bucketElemetnCounts[k]; l++) {
					// 取出元素放入到原数组
					arr[index] = bucket[k][l];
					index++;
				}
			}
			// 特别注意,我们在第二次向桶里面放数据时,桶里面应该是空的
			bucketElemetnCounts[k] = 0;
		}
		System.out.println("第一轮,对个位数的排序处理:" + Arrays.toString(arr));
		// 第二轮(针对每个元素的十位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket1 = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts1 = new int[10];

		// 第二轮(针对每个元素的十位进行排序处理)
		for (int j = 0; j < arr.length; j++) {
			// 取出每个元素的个位的值
			int digitOfElement = arr[j] / 10 % 10;
			// 放入到对应的桶中
			// 说明:比如说我的第一个数为234,234/10=23 23%10=3
			// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
			bucket1[digitOfElement][bucketElemetnCounts1[digitOfElement]] = arr[j];
			bucketElemetnCounts1[digitOfElement]++;
		}
		// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
		index = 0;
		// 遍历每一个桶,并将桶中的数据,放入到原数组
		for (int k = 0; k < bucketElemetnCounts1.length; k++) {
			// 如果桶中有数据,我们才取
			if (bucketElemetnCounts1[k] != 0) {
				// 遍历该桶
				for (int l = 0; l < bucketElemetnCounts1[k]; l++) {
					// 取出元素放入到原数组
					arr[index] = bucket1[k][l];
					index++;
				}
			}
			// 特别注意,我们在第三次向桶里面放数据时,桶里面应该是空的
						bucketElemetnCounts[k] = 0;
		}
		System.out.println("第二轮,对十位数的排序处理:" + Arrays.toString(arr));		
	}
}

第一轮,对个位数的排序处理:[3, 234, 34, 5, 135, 48]
第二轮,对十位数的排序处理:[3, 5, 234, 34, 135, 48]

3.第三轮

public class RadixSort {

	public static void main(String[] args) {
		int[] arr = { 5, 234, 34, 48, 135, 3 };
		radixSort(arr);

	}

	public static void radixSort(int[] arr) {
		// 第一轮(针对每个元素的个位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts = new int[10];

		// 第一轮(针对每个元素的个位进行排序处理)
		for (int j = 0; j < arr.length; j++) {
			// 取出每个元素的个位的值
			int digitOfElement = arr[j] % 10;
			// 放入到对应的桶中
			// 说明:比如说我的第一个数为5234,5%10=0
			// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
			bucket[digitOfElement][bucketElemetnCounts[digitOfElement]] = arr[j];
			bucketElemetnCounts[digitOfElement]++;
		}
		// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
		int index = 0;
		// 遍历每一个桶,并将桶中的数据,放入到原数组
		for (int k = 0; k < bucketElemetnCounts.length; k++) {
			// 如果桶中有数据,我们才取
			if (bucketElemetnCounts[k] != 0) {
				// 遍历该桶
				for (int l = 0; l < bucketElemetnCounts[k]; l++) {
					// 取出元素放入到原数组
					arr[index] = bucket[k][l];
					index++;
				}
			}
			// 特别注意,我们在第二次向桶里面放数据时,桶里面应该是空的
			bucketElemetnCounts[k] = 0;
		}
		System.out.println("第一轮,对个位数的排序处理:" + Arrays.toString(arr));
		// 第二轮(针对每个元素的十位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket1 = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts1 = new int[10];

		// 第二轮(针对每个元素的十位进行排序处理)
		for (int j = 0; j < arr.length; j++) {
			// 取出每个元素的个位的值
			int digitOfElement = arr[j] / 10 % 10;
			// 放入到对应的桶中
			// 说明:比如说我的第一个数为234,234/10=23 23%10=3
			// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
			bucket1[digitOfElement][bucketElemetnCounts1[digitOfElement]] = arr[j];
			bucketElemetnCounts1[digitOfElement]++;
		}
		// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
		index = 0;
		// 遍历每一个桶,并将桶中的数据,放入到原数组
		for (int k = 0; k < bucketElemetnCounts1.length; k++) {
			// 如果桶中有数据,我们才取
			if (bucketElemetnCounts1[k] != 0) {
				// 遍历该桶
				for (int l = 0; l < bucketElemetnCounts1[k]; l++) {
					// 取出元素放入到原数组
					arr[index] = bucket1[k][l];
					index++;
				}
			}
			// 特别注意,我们在第三次向桶里面放数据时,桶里面应该是空的
						bucketElemetnCounts[k] = 0;
		}
		System.out.println("第二轮,对十位数的排序处理:" + Arrays.toString(arr));
		
			  	// 第三轮(针对每个元素的百位进行排序处理)

				// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
				// 说明:
				// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
				int[][] bucket2 = new int[10][arr.length];

				// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
				// 可以这样理解
				// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
				int[] bucketElemetnCounts2 = new int[10];

				// 第三轮(针对每个元素的百位进行排序处理)
				for (int j = 0; j < arr.length; j++) {
					// 取出每个元素的个位的值
					int digitOfElement = arr[j] / 100 % 10;
					// 放入到对应的桶中
					// 说明:比如说我的第一个数为234,234/10=23 23%10=3
					// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
					bucket2[digitOfElement][bucketElemetnCounts2[digitOfElement]] = arr[j];
					bucketElemetnCounts2[digitOfElement]++;
				}
				// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
				index = 0;
				// 遍历每一个桶,并将桶中的数据,放入到原数组
				for (int k = 0; k < bucketElemetnCounts2.length; k++) {
					// 如果桶中有数据,我们才取
					if (bucketElemetnCounts2[k] != 0) {
						// 遍历该桶
						for (int l = 0; l < bucketElemetnCounts2[k]; l++) {
							// 取出元素放入到原数组
							arr[index] = bucket2[k][l];
							index++;
						}
					}
				}
				System.out.println("第三轮,对百位数的排序处理:" + Arrays.toString(arr));
	}
}
第一轮,对个位数的排序处理:[3, 234, 34, 5, 135, 48]
第二轮,对十位数的排序处理:[3, 5, 234, 34, 135, 48]
第三轮,对百位数的排序处理:[3, 5, 34, 48, 135, 234]

4.代码优化

public class RadixSort1 {

	public static void main(String[] args) {
		int[] arr = { 5, 234, 34, 48, 135, 3 };
		radixSort(arr);
		System.out.println(Arrays.toString(arr));

	}

	public static void radixSort(int[] arr) {
		// 第一轮(针对每个元素的个位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts = new int[10];

		int max = 0;
		// 遍历求出最大值
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		int maxLength = (max + "").length();
		for (int j = 0, n = 1; j < maxLength; j++, n *= 10) {
			// 针对每个元素的位进行排序处理
			for (int l = 0; l < arr.length; l++) {
				// 取出每个元素的个位的值
				int digitOfElement = arr[l] / n % 10;
				// 放入到对应的桶中
				// 说明:比如说我的第一个数为5234,5%10=0
				// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
				bucket[digitOfElement][bucketElemetnCounts[digitOfElement]] = arr[l];
				bucketElemetnCounts[digitOfElement]++;
			}
			// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
			int index = 0;
			// 遍历每一个桶,并将桶中的数据,放入到原数组
			for (int k = 0; k < bucketElemetnCounts.length; k++) {
				// 如果桶中有数据,我们才取
				if (bucketElemetnCounts[k] != 0) {
					// 遍历该桶
					for (int l = 0; l < bucketElemetnCounts[k]; l++) {
						// 取出元素放入到原数组
						arr[index] = bucket[k][l];
						index++;
					}
				}
				// 特别注意,我们在第二次向桶里面放数据时,桶里面应该是空的
				bucketElemetnCounts[k] = 0;
			}
		}

	}
}
[3, 5, 34, 48, 135, 234]

7.3测试基数排序算法的速度

public class RadixSort1 {

	public static void main(String[] args) {
		int[] arr = new int[80000];
		for (int i = 0; i < 80000; i++) {
			arr[i] = (int) (Math.random() * 800000);
		}
		Date date1 = new Date();
		SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String format1 = simpleDateFormat1.format(date1);
		System.out.println("排序前的时间是:" + format1);
		radixSort(arr);
		Date date2 = new Date();
		SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String format2 = simpleDateFormat2.format(date2);
		System.out.println("排序后的时间是:" + format2);

	}

	public static void radixSort(int[] arr) {
		// 第一轮(针对每个元素的个位进行排序处理)

		// 定义一个二维数组,表示10个桶,每个桶就是一个一维数组
		// 说明:
		// 为了防止放入数据时溢出,每一个一维数组的大小定为arr.length
		int[][] bucket = new int[10][arr.length];

		// 为了记录每个桶中,实际存放了多少个数据,定义一个一维数组来记录美再次放入的数据个数
		// 可以这样理解
		// 比如说:bucketElemetnCounts[0],记录的就是bucket[0]桶的放入数据的个数
		int[] bucketElemetnCounts = new int[10];

		int max = 0;
		// 遍历求出最大值
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		int maxLength = (max + "").length();
		for (int j = 0, n = 1; j < maxLength; j++, n *= 10) {
			// 针对每个元素的位进行排序处理
			for (int l = 0; l < arr.length; l++) {
				// 取出每个元素的个位的值
				int digitOfElement = arr[l] / n % 10;
				// 放入到对应的桶中
				// 说明:比如说我的第一个数为5234,5%10=0
				// bucketElemetnCounts[digitOfElement]=bucketElemetnCounts[0]
				bucket[digitOfElement][bucketElemetnCounts[digitOfElement]] = arr[l];
				bucketElemetnCounts[digitOfElement]++;
			}
			// 按照这个桶的顺序(一维数组的下标依次取出数据,放入原来的数组)
			int index = 0;
			// 遍历每一个桶,并将桶中的数据,放入到原数组
			for (int k = 0; k < bucketElemetnCounts.length; k++) {
				// 如果桶中有数据,我们才取
				if (bucketElemetnCounts[k] != 0) {
					// 遍历该桶
					for (int l = 0; l < bucketElemetnCounts[k]; l++) {
						// 取出元素放入到原数组
						arr[index] = bucket[k][l];
						index++;
					}
				}
				// 特别注意,我们在第二次向桶里面放数据时,桶里面应该是空的
				bucketElemetnCounts[k] = 0;
			}
		}

	}
}

排序前的时间是:2021-01-09 21:03:18
排序后的时间是:2021-01-09 21:03:18
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值