(Algorithm) image example to take you to understand bucket sorting

concept elaboration

A sort that does not require comparison ( ratio, such as 1<3) (its essence is to use the number of each digit of the number to sort)

There is an array arr=[100,31,21,43], please sort it

As the name suggests, we need to prepare several buckets ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], so ten are enough) , an additional list (count, bucket), We first traverse the entire array to find the largest number and obtain its number of digits. Here, the largest number is 100 and the number of digits is 3. The number of digits is the number of times we want to enter and exit the bucket.

first barrel

find a single digit 

Traverse the array arr from right to left, the first 43, single digit 3, count[3] +=1

The second 21, single digit 1, count[1] +=1

The third 31, single digit 1, count[1] +=1

The fourth 100, single digit 0, count[0] +=1

get count = [1,2,0,1,0,0,0,0,0,0]

Add the number in each digit to the number in the left position, and the resulting sum is used as the value of the position, which is equal to the number of numbers smaller than the value of the position

get count =  [1, 3, 3, 4, 4, 4, 4, 4, 4, 4]

For example, the number in position 1 is 3, which means: there are 3 numbers with the ones digit less than or equal to 3

Next sort on the bucket

Traversing from right to left, 43 digits are 3, count[3] - 1 = 3, 43 is placed in bucket[3], which is equal to the first time sorting 43 in the third place

21 digits 1, count[1] - 1 = 2, 21 into bucket[2]

31 digits 1, count[1] - 1 = 1, 31 into bucket[1]

Each digit of 100 is 0, count[0] - 1 = 0, 100 is placed in bucket[0]

get bucket = [100,31,21,43], copy to arr

count becomes the initial state

Second barrel

find tens

From right to left, the first 43, tens digit 3, count[4] +=1

The second 21, tens digit 2, count[2] +=1

The third 31, tens digit 3, count[3] +=1

The fourth 100, tens digit 0, count[0] +=1

get count = [1,0,1,1,1,0,0,0,0,0]

After adding count = [1, 1, 2, 3, 4, 4, 4, 4, 4, 4]

Traversing from right to left, 43 tens digit 3, count[4] - 1 = 3, 43 into bucket[3]

21 tens digit 2, count[2] - 1 = 1, 21 into bucket[1]

31 tens digit 3, count[3] - 1 = 2, 31 into bucket[2]

Each digit of 100 is 0, count[0] - 1 = 0, 100 is placed in bucket[0]

bucket = [100, 21, 31, 43], copy to arr

barreled three times

find hundreds

From right to left, the first 43, hundreds digit 0, count[4] +=1

The second 31, the hundreds digit is 0, count[0] +=1

The third 21, the hundreds digit is 0, count[0] +=1

The fourth 100, hundreds digit 1, count[1] +=1

get count = [3,1,0,0,0,0,0,0,0,0]

After adding count = [3, 4, 4, 4, 4, 4, 4, 4, 4, 4]

Traversing from right to left, 43 tens digit 3, count[0] - 1 = 2, 43 into bucket[2]

31 tens digit 2, count[2] - 1 = 1, 21 into bucket[1]

21 tens digit 3, count[3] - 1 = 0, 31 into bucket[0]

Each digit of 100 is 0, count[0] - 1 = 3, 100 is placed in bucket[3]

bucket = [21, 31, 43, 100], copy to arr

The entire array is ordered, and there is no comparison process

Why can it be sorted after entering and exiting the bucket several times?

Because we start from the single digit, the priority of each round of sorting is the value of the last digit

Implementation of the code (Java):

//重载radixSort,可以求某个范围的有序,或直接输入数组令它有序
public static void radixSort(int[] arr){
    if(arr = null || arr.length < 2){
        return;
    }
    radixSort(arr,0,arr.length-1,maxdigit(arr))
}

//获取一个数组中最大的数值的位数,作为我们的入桶次数
public static int maxdigit(int[] arr){
    max = Integer.MIN_VALUE;
    for(int i=0,i<arr.length-1,i++){
        max = math.max(max,arr[i]);
        }
    int res = 0;
    while(max > 0){
        res++;
        max = max / 10;
    }
    return res; 
}

//获取某个数字的第d位上的数字
public static int getdigit(int x,int d) {
    return x / (math.power(10,d-1)) % 10
}

//桶排序
public static void radixSort(int[] arr, int L, int R,digit){
    final int ridax = 10;
    arr[] bucket = new int[R-L+1];
    int i = 0;
    int j = 0;
    //入桶digit次
    for(int d = 1;d <= digit; d++){
        int[] count = new int[radix]
        //从右往左遍历,获取每个数字的d位上的数字,将数据记录入count
        for(i = R, i >=0,i--){    
            j = getdigit(arr[i],d);
            count[j +=1];
        }
        //将count从每个位置上的数左往右相加,的和
        for(i = 1;i<radix;i++){
            count[i] = count[i] + count[i-1];
        }
        //按照得到的count,从右往左将arr重新排列存入bucket
        for(i = R; i >= 0; i--){
            j = getdigit(arr[i],d)
            count[j] -= 1;
            bucket[count[j]] = arr[i];
        }
        //将排好的bucket复制到arr
        for(i<=R;i++){
            bucket[i] = arr[i];
        }
    }
}

(ps: Explain why we need a bucket list as a transitional storage, because every time we rely on count to sort, we must follow the order of the last discharge. If we directly transfer arr, some data will be overwritten in advance)

Guess you like

Origin blog.csdn.net/qq_48860282/article/details/124024689