기본 정렬
소개
1) 기수 정렬 (radixsort)은 ** "bucket sort **"(버킷 정렬) 또는 binsort로도 알려진 " distribution sort"(distributionsort) 에 속합니다. 이름에서 알 수 있듯이 각 비트의 값으로 정렬 됩니다. 키 값 의 요소는 정렬 효과를 얻기 위해 일부 "버킷"에 할당됩니다 .
2) 기수 정렬 방법은 안정적인 정렬 이고 기수 정렬 방법은 효율적이고 안정적인 정렬 방법입니다.
3) 기수 정렬 ( RadiXSort) 는 버킷 정렬입니다. 확장
4) 기본 번호 정렬은 1887 년 Hermann Holly에 의해 발명되었습니다. 이는 다음과 같이 구현됩니다. 정수는 자릿수에 따라 다른 숫자로 잘린 다음 각 자릿수에 따라 비교됩니다.
도표
생각 정렬
동일한 숫자 길이와 비교할 모든 값을 통합하고 더 짧은 숫자로 숫자 앞에 0을 채 웁니다. 그런 다음 가장 낮은 비트부터 시작하여 순서대로 한 번 정렬합니다. 이렇게하면 가장 낮은 순서에서 가장 높은 순서로 순서가 지정된 순서가됩니다.
이해
즉, 숫자를 세어 해당 위치에 넣습니다. 예를 들어 3 열에 3을, 1 열에 41을 넣습니다. 3이 한 자릿수이고 앞에 0이 추가되면 어떻게 될까요? . 03이고 3 열은 버킷 중 하나이고 1은 버킷, 51은 1 버킷, 23은 3 버킷에도 있습니다.
즉, 0-9에서 10 개의 버킷이 있습니다 (정확히 10 개의 버킷이 아닐 수도 있음).
주제 : HKUST 팀의 점수는 53,3,542,748,14,214입니다. 기수 정렬 방법을 사용하여이 사람들의 점수를 가장 작은 것부터 가장 큰 것까지 정렬하십시오.
단계
1. 각 요소의 한 자리를 꺼내 해당 버킷에이 숫자를 넣습니다 ( 버킷은 1 비트의 배열입니다 ).
2. 버킷 (1 차원 배열 첨자)의 순서에 따라 데이터를 순서대로 꺼내 원래 배열에 다시 넣습니다.
3. 배열 정렬의 첫 번째 라운드
542 53 3 14214748
4. 방금 전 작업에 따라 542 53 3 14 214 748을 다시 수행하지만 이번에는 10 자리 숫자로 이동하여 버킷을 지정합니다.
0 배럴 3
1 배럴 14214
4 배럴 542748
53 개 배럴 5 개
원래 배열로 돌아 가기
5. 두 번째 정렬 결과
3 14214542748 53
6. 세 번째 라운드에서 동일한 이유는 두 번째 정렬을 기준으로 100 자리 숫자로 버킷을 정의하기 때문입니다.
0 배럴 3 14 53
2 배럴 214
5 배럴 542
7 배럴 748
세 번째 정렬의 결과
3 14 53214542748이 최종 결과입니다.
재귀 적 단계가 없다는 것을 알 수 있는데 몇 번이나 걸리나요? 배열에서 가장 큰 숫자의 자릿수에 따라 다릅니다.이 배열에서 748의 가장 큰 숫자는 100 자릿수이므로 3 자릿수입니다. 4 자릿수이면 4 번입니다.
코드 유도
//基数排序方法
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));
}
최종 코드
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));
}
}
}