JAVA代码实现基数排序

[亡魂溺海] 提交于 2020-02-27 19:20:04

基数排序

基数排序是经典的拿空间换时间的排序算法。当预排数据中有重复数据时,该算法排完序后,重复数据的相对顺序仍然不变,即表明基数排序是一种稳定排序算法。其基本思想如下:第一轮按每个数的个位数的顺序,将数放入0-9的10个桶中,然后按顺序取出来放回原数组;第二轮按每个数的十位数的顺序,将数放入0-9的10个桶中,然后按顺序取出来放回原数组;依次类推。

其代码步骤如下:

  1. 得到数组中最大数的位数,确定需要排几轮;
  2. 定义一个长度为10的二维数组模拟10个桶,其中每个桶的长度为原数组的长度;
  3. 定义一个一维数组用来记录每一轮的每个桶中放了多少个数据;
  4. 每一轮先按每个数个位、十位、百位.的顺序放入桶中;放完之后再按桶的顺序将每个数放回到原数组。直至排完

特别注意:

  1. 基数排序是经典的拿空间(内存)换时间的排序算法,当预排数据量过于庞大时,耗费的内存也会很大,一定要注意硬件内存是否够用,否则会出现内存不足的错误。
  2. 上述过程不满足于预排数据中有负数的情况,当预排数据中存在负数,算法步骤要进行相应调整。

每一步的详细说明已在代码中注释,如有错误,还望指出,我会及时改正。

package com.sort.radixSort;

import java.util.Arrays;

/*
 * 基数排序
 */
public class RadixSortDemo1 {

	public static void main(String[] args) {
		int[] array = { 53, 3, 542, 748, 14, 214 };
		System.out.println("排序前:" + Arrays.toString(array));
		radixSort(array);
		System.out.println("排序后:" + Arrays.toString(array));

	}

	// 基数排序
	public static void radixSort(int[] array) {
		// 1.首先要拿到数组中最大的数,确定需要几轮排序
		int max = array[0];
		for (int i = 0; i < array.length; i++) {
			if (array[i] > max) {
				max = array[i];
			}
		}
		// 得到最大数的位数,确定循环几轮
		int maxLength = (max + "").length();
		// 2.定义一个二维数组用来模拟10个桶,为了防止每个桶在插入数据的时候发生溢出,每个桶的长度规定为数组的长度
		int[][] bucket = new int[10][array.length];
		// 3.定义一个一维数组用来记录每个桶中放了多少个数据(也是下次新数据的下标)
		int[] bucketEleCounts = new int[10];

		// 4.所有准备工作完毕,开始排序
		// 一共需要排maxLength轮
		for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {// n专门用来辅助得到每轮的位数

			// 4.1.循环数组,按位数顺序放入对应的桶中
			for (int j = 0; j < array.length; j++) {
				// 每轮得到数组中每个数相应的位数
				int ele = array[j] / n % 10;
				// 放入到对应的桶中,找到第ele个桶,然后得到第ele个桶中放新数据的下标bucketEleCounts[ele]
				bucket[ele][bucketEleCounts[ele]] = array[j];
				// 每次放完,需要将第ele个桶的数量+1;
				bucketEleCounts[ele]++;
			}

			// 4.2.放完数据后,按桶的顺序依次把数据取出来放回原来的数组
			int index = 0;
			for (int k = 0; k < bucket.length; k++) {
				// 如果第k个桶有数据,那就取出来
				if (bucketEleCounts[k] != 0) {
					// 第k个桶里面的数据循环取出来,并且放回原数组
					for (int l = 0; l < bucketEleCounts[k]; l++) {
						array[index] = bucket[k][l];
						index++;
					}
				}
				// 每次取完一个桶的数据,就要将这个桶的数据个数清空,等待下一轮排序
				bucketEleCounts[k] = 0;
			}

			System.out.println("第" + (i + 1) + "轮排序后:" + Arrays.toString(array));
		}
	}

}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!