Cardinality sort - radius sort

Posted by SundayDriver on Mon, 28 Feb 2022 00:06:20 +0100

Cardinality sort

Introduction to cardinality sorting (bucket sorting):

  1. radix sort belongs to "distribution sort", also known as "bucket sort" or bin sort. As the name suggests, it allocates the elements to be sorted to some "buckets" through the values of each bit of the key value
  2. The cardinal ranking method is a stable ranking method, and the cardinal ranking method is a stable ranking method with high efficiency
  3. Radix sort is an extension of bucket sort
  4. Cardinality sorting was invented by Herman hollery in 1887. It is realized in this way: the integer is cut into different numbers according to the number of bits, and then compared according to each number of bits.

Basic idea of cardinality sorting

  1. Unify all values to be compared into the same digit length, and fill zero in front of the shorter digit. Then, start from the lowest order and sort once in turn. In this way, the sequence will become an ordered sequence from the lowest order to the highest order.
  2. This explanation is difficult to understand. Let's take a graphic explanation to understand the steps of cardinality sorting
    Sort the array {53, 3, 542, 748, 14, 214} in ascending order using cardinality

code implementation

package com.iflytek.sort;


import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class RadixSort {

    public static void main(String[] args) {
//        int arr[] = {53, 3, 542, 748, 14, 214};


        int arr[] = new int[8000000];
        for (int i = 0; i < 8000000; i++) {
            arr[i] = (int) (Math.random() * 80000);
        }
        Date date1 = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd:hh:mm:ss");
        String format = dateFormat.format(date1);
        System.out.println(format);
        radixSort(arr);
        Date date2 = new Date();
        String format1 = dateFormat.format(date2);
        System.out.println(format1);
//        System.out.println(Arrays.toString(arr));
    }

    public static void radixSort(int arr[]) {
        //1. Get the number of digits of the largest number in the array
        int max = arr[0];//Suppose the first number is the maximum number
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        //What is the maximum number
        int maxLength = (max + "").length();

        //Define a two-dimensional array, representing 10 buckets, and each bucket is a one-dimensional array
        // explain
        // 1. The two-dimensional array contains 10 one-dimensional arrays
        // 2. In order to prevent data overflow when putting in numbers, the size of each one-dimensional array (bucket) is set to arr.length
        // 3. The name is clear, and cardinality sorting is a classical algorithm that uses space for time
        int[][] bucket = new int[10][arr.length];
        //In order to record how many data are actually stored in each bucket, we define a one-dimensional array to record the number of data put in each bucket
        // It can be understood here / / for example: bucketElementCounts[0], which records the number of data put into the bucket[0]
        int[] bucketElementCounts = new int[10];

        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            //(sort the corresponding bits of each element). The first is a bit, the second is a ten bit, and the third is a hundred bit
            for (int j = 0; j < arr.length; j++) {
                //Take out the value of the corresponding bit of each element
                int digitOfElement = arr[j] / n % 10;
                //Put it into the corresponding bucket
                bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
                bucketElementCounts[digitOfElement]++;
            }
                //According to the order of this bucket (the subscript of one-dimensional array takes out the data in turn and puts it into the original array)
                int index=0;
                //Traverse each bucket, and put the data in the bucket into the original array
                for (int k = 0; k < bucketElementCounts.length; k++) {
                    //If there is data in the bucket, we put it into the original array
                    if (bucketElementCounts[k]!=0){
                        //Cycle the bucket, i.e. the k-th bucket (i.e. the k-th one-dimensional array), and put it into
                        for (int l = 0; l < bucketElementCounts[k]; l++) {
                            //Take out elements and put them into arr
                            arr[index++] = bucket[k][l];
                        }
                    }
                    //After the i+1 round of processing, each bucket elementcounts [k] = 0!!!!
                    bucketElementCounts[k] = 0;
                }
//                System.out.println("the" + (i+1) + "round, sorting of individual bits, arr =" + arrays toString(arr));



        }
    }
}

Description of cardinality sorting:

  1. Cardinality sorting is an extension of traditional bucket sorting, which is very fast
  2. Cardinality sorting is a classic space for time method, which takes up a lot of memory. When sorting massive data, it is easy to cause OutOfMemoryError.
  3. Cardinality sorting is stable. [Note: it is assumed that there are multiple records with the same keyword in the record sequence to be sorted. If they are sorted, the relative order of these records remains unchanged, that is, in the original sequence, r[i]=r[j], and r[i] is before r[j], while in the sorted sequence, r[i] is still before r[j], then this sorting algorithm is said to be stable; Otherwise, it is called unstable]
  4. For arrays with negative numbers, we don't need to sort by cardinality. If you want to support negative numbers, refer to: Cardinal ordering of complex numbers

Topics: Algorithm data structure