Algorithm notes-radix sorting

Base sort

Introduction

1) Radix sort (radixsort) belongs to " distribution sort" (distributionsort) , also known as **"bucket sort**" (bucket sort) or binsort, as the name implies, it is sorted by the value of each bit of the key value The elements of are allocated to some "buckets" to achieve the effect of sorting.
2) The radix sort method is a stable sort , and the radix sort method is an efficient and stable sort method.
3) The radix sort (RadiXSort) is a bucket sort Extension
4) Cardinal number sorting was invented in 1887 by Hermann Holly. It is implemented like this: the integer is cut into different numbers according to the digits, and then compared according to each digit.

Diagram

img

Sorting thought

Unify all the values ​​to be compared to the same digit length, and padded zeros in front of the numbers with shorter digits. Then, starting from the lowest bit, sort one time in sequence. In this way, from the lowest order to the highest order, the sequence becomes an ordered sequence.

understanding

That is to say, we count the numbers and put them in the corresponding position. For example, we put 3 in the 3 column and 41 in the 1 column. What if the 3 is a single digit, and a zero is added in front. It is 03, then the 3 column is our bucket, 1 is also a bucket, 51 is also in the 1 bucket, and 23 is also in the 3 bucket.

In other words, we have 10 buckets from 0-9 (not necessarily exactly 10 buckets)

Topic: The HKUST team has the following scores: 53,3,542,748,14,214. Please use the base number method to sort the scores of these people from smallest to largest

step

1. Take out the single digit of each element, and then put this number in the corresponding bucket (a bucket is an array of one bit )

2. Take out the data in sequence according to the order of the bucket (one-dimensional array subscript) and put it back into the original array

3. The first round of sorting of the array

542 53 3 14 214 748

4. According to the operation just now, we will do 542 53 3 14 214 748 again, but this time we will go to ten digits to specify our bucket

0 barrels 3

1 barrel 14 214

4 barrels 542 748

5 barrels of 53

Return to the original array

5. The second round of sorting results

3 14 214 542 748 53

6. In the third round, the same reason is that on the basis of the second round of sorting, we define our buckets according to the hundred digits.

0 barrel 3 14 53

2 barrels 214

5 barrels 542

7 barrels 748

The result of the third sort

3 14 53 214 542 748 is our final result

We can see that there is no recursive step. How many times does it take? Depends on the number of digits of the largest number in our array. The largest number of 748 in this array has the largest number of digits, so it is 3 digits. For 4 digits, 4 times are required.

Derive the code

	//基数排序方法
	public static void radixSort(int[] arr){
    
    
		//第一轮排序(针对每个元素的个位进行排序)
		//定义一个二维数组,表示10个桶,每个桶就是一个一位数组
		//说明
		//1.二维数组包含10个一位数组,但是一位数组要多大?
		//2.为了防止再放入数字的时候,数据溢出,则我们每个一位数组(桶)大小定位arr.length
		//基数排序也就是空间换时间的算法
		int[][] bucket = new int[10][arr.length];//这个桶要多大?
		//我们怎么把数据从桶中取出来呢?我们桶中实际有多少个数据呢?
		//为了记录,我们定义一个一维数组来记录各个桶中每次放入的个数
		//bucketElementCounts[0]就是记录0桶中有几个数据
		int[] bucketElementCounts = new int[10];
		//第一轮
		for(int j = 0;j < arr.length;j++){
    
    
			//取出个位数字
			int digitOfElement = arr[j] %10;
			//放入到对应的桶中
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
			bucketElementCounts[digitOfElement]++;
		}
		//重新放回原数组
		int index = 0;
		//遍历每一个桶,并将桶中的数据放入到原数组
		for(int  k = 0; k < bucketElementCounts.length;k++){
    
    
			//如果桶中有数据
			if(bucketElementCounts[k] != 0){
    
    
				//循环该桶  即第k个桶,即第k个一维数组
				for(int l = 0;l < bucketElementCounts[k];l++){
    
    
					//取出元素,放回原数组
					arr[index] = bucket[k][l];
					index++;
				}
				//第一轮取出数据后,需要将每个bucketElementCounts[k] = 0
				//为了我们第二轮第三轮处理的时候,没有数据
				bucketElementCounts[k] = 0;
			}
		}
		System.out.println("第一轮对个位的排序处理"+Arrays.toString(arr));
		
		//第二轮处理
		for(int j = 0;j < arr.length;j++){
    
    
			//取出个位数字
			int digitOfElement = arr[j] /10 %10;
			//放入到对应的桶中
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
			bucketElementCounts[digitOfElement]++;
		}
		//重新放回原数组
		index = 0;
		//遍历每一个桶,并将桶中的数据放入到原数组
		for(int  k = 0; k < bucketElementCounts.length;k++){
    
    
			//如果桶中有数据
			if(bucketElementCounts[k] != 0){
    
    
				//循环该桶  即第k个桶,即第k个一维数组
				for(int l = 0;l < bucketElementCounts[k];l++){
    
    
					//取出元素,放回原数组
					arr[index] = bucket[k][l];
					index++;
				}
				bucketElementCounts[k] = 0;
			}
		}
		System.out.println("第二轮对十位的排序处理"+Arrays.toString(arr));
		//第三轮
		for(int j = 0;j < arr.length;j++){
    
    
			//取出个位数字
			int digitOfElement = arr[j] /100;
			//放入到对应的桶中
			bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
			bucketElementCounts[digitOfElement]++;
		}
		//重新放回原数组
		index = 0;
		//遍历每一个桶,并将桶中的数据放入到原数组
		for(int  k = 0; k < bucketElementCounts.length;k++){
    
    
			//如果桶中有数据
			if(bucketElementCounts[k] != 0){
    
    
				//循环该桶  即第k个桶,即第k个一维数组
				for(int l = 0;l < bucketElementCounts[k];l++){
    
    
					//取出元素,放回原数组
					arr[index] = bucket[k][l];
					index++;
				}
				bucketElementCounts[k] = 0;
			}
		}
		System.out.println("第三轮对百位的排序处理"+Arrays.toString(arr));
	}

Final code

import java.util.Arrays;

//基数排序
//@author   王庆华
//2021年1月14日13:39:02
public class RadioxSort {
    
    
	public static void main(String[] args) {
    
    
		int arr[] = {
    
    53,3,542,748,14,214};
		radixSort(arr);
		
	}
	//基数排序方法
	public static void radixSort(int[] arr){
    
    
		//1.得到数组中最大数的位数
		int max = arr[0];//假设第一个数就是最大数
		for(int i=1;i < arr.length;i++){
    
    
			if(arr[i] > max){
    
    
				max = arr[i];
			}
		}
		//得到最大数是几位数
		int maxLength = (max+"").length();//变成字符串
		int[][] bucket = new int[10][arr.length];
		int[] bucketElementCounts = new int[10];
		//使用循环对代码处理
		for(int i = 0, n = 1;i<maxLength;i++,n*=10){
    
    
			//针对每个元素的对应的位数进行排序
			for(int j = 0;j < arr.length;j++){
    
    
				//取出个位数字
				int digitOfElement = arr[j] /n %10;
				//放入到对应的桶中
				bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
				bucketElementCounts[digitOfElement]++;
			}
			//重新放回原数组
			int index = 0;
			//遍历每一个桶,并将桶中的数据放入到原数组
			for(int  k = 0; k < bucketElementCounts.length;k++){
    
    
				//如果桶中有数据
				if(bucketElementCounts[k] != 0){
    
    
					//循环该桶  即第k个桶,即第k个一维数组
					for(int l = 0;l < bucketElementCounts[k];l++){
    
    
						//取出元素,放回原数组
						arr[index] = bucket[k][l];
						index++;
					}
					//第一轮取出数据后,需要将每个bucketElementCounts[k] = 0
					//为了我们第二轮第三轮处理的时候,没有数据
					bucketElementCounts[k] = 0;
				}
			}
			System.out.println("第"+(i+1)+"轮对个位的排序处理"+Arrays.toString(arr));
		}
	}
}

Guess you like

Origin blog.csdn.net/qq_22155255/article/details/112620310