The ranking algorithm that interviewers like to ask

Keywords: Algorithm Back-end

preface

After a year of self-study, JAVA ABA finally made an appointment for an interview. However, the interviewer asked her to talk about her understanding of sorting algorithm.

Interviewer: do you know anything about algorithms? Sort this one, okay?

ABBA ABBA: understand that the sorting algorithm mainly includes bubble sort, insert sort, Hill sort, selection sort, quick sort, merge sort, heap sort, cardinal sort and bucket sort.

Interviewer: very good. Do you know what stability is? Are these algorithms stable? How complex are they?

ABBA ABBA: stability means that if there are two elements a and b, and a = b, and a is in front of b, if after sorting, b is in front of a, then we say that the algorithm is unstable, which is stability. Unstable algorithms include quick sort, selective sort, Hill sort and heap sort. It is commonly known as the "quick election heap.".

ABBA ABBA: as shown in the following figure (dog head), we can see that the average performance is O(nlogn): quick sort, merge sort and heap sort. These sorting algorithms have low time complexity and are suitable for sorting large data sets. Of course, sorting algorithms with high time complexity also have their own use of force.

Interviewer: tell me about the usage scenario of the algorithm you know

ABBA ABBA:

Bubble sorting is suitable: it is applicable to the situation where the amount of data is small, the sorting is required to be stable, and the amount of data itself is basically orderly.

Selection sorting is suitable: when the amount of data is small and there is no requirement for stability (compared with bubble sorting, the number of exchanges is reduced).

Insertion sort: it is suitable for the situation that the amount of data is small, the stability of the algorithm is required, and the local order or the overall order is relatively orderly.

Merge sort is suitable for the situation where the data is large and the stability of the algorithm is required.

Quick sort is suitable for situations with large amount of data, scattered data and no requirements for stability.

Heap sorting is suitable for situations with large amount of data and no requirements for stability.

Hill sort: Hill sort is an optimization of direct insertion sort, which can be used for large arrays. Hill sort is much faster than insertion sort and selection sort, and the larger the array, the greater the advantage.

Cardinality sorting: it is suitable for scenarios where there is no particularly large data in the data set and the algorithm is required to be stable.

Bucket sorting: it is suitable for scenarios with concentrated data and stable algorithm requirements.

Interviewer: OK, I see you are well prepared. Let me ask an unexpected one. Can you give me a detailed introduction to cardinality sorting and bucket sorting?

ABBA ABBA: Cardinal sorting belongs to "distributive sorting", also known as "bucket method" or bin sort. As the name suggests, it allocates the elements to be sorted to some "buckets" through some information of key values, so as to achieve the function of sorting. For example, if there is a batch of data [31,19,46,23,17], sort it according to the value in the "number" bit and put it into the following bucket.

ABBA ABBA: put it into the bucket and get the result as shown in the figure below.

ABBA ABBA: then continue to sort the elements in the bucket, take them out from the 0 bucket to the 9 bucket, and continue sorting to get the blue data.

ABBA ABBA: then continue to sort the elements in the bucket, take them out from the 0th bucket to the 9th bucket, continue to sort, get the blue part of the data, continue to sort the blue part of the data, and sort according to the number on the "ten digits".

ABBA ABBA: finally, take out these data from the 0th bucket to the 9th bucket, so that they are all in order.

Interviewer: Yes, yes. If the number is very large, it seems to be very unfavorable to the ranking?

ABBA ABBA: Yes, if there is a large number, it will be very difficult to sort the cardinality. It is best that the data in the dataset is almost large.

 /**
 * Cardinality sort
 */
public class RadixSort {

    /**
     * Get the highest number of digits
     */
    private int getMaxDigit(int[] arr) {
        int maxValue = getMaxValue(arr);
        return getNumLenght(maxValue);
    }

    private int getMaxValue(int[] arr) {
        int maxValue = arr[0];
        for (int value : arr) {
            if (maxValue < value) {
                maxValue = value;
            }
        }
        return maxValue;
    }

    protected int getNumLenght(long num) {
        if (num == 0) {
            return 1;
        }
        int lenght = 0;
        for (long temp = num; temp != 0; temp /= 10) {
            lenght++;
        }
        return lenght;
    }

    private int[] radixSort(int[] arr, int maxDigit) {
        int mod = 10;
        int dev = 1;

        for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
            // Considering the negative number, the number of queues is doubled here, where [0-9] corresponds to a negative number and [10-19] corresponds to a positive number (bucket + 10)
            int[][] counter = new int[mod * 2][0];

            for (int j = 0; j < arr.length; j++) {
                int bucket = ((arr[j] % mod) / dev) + mod;
                counter[bucket] = arrayAppend(counter[bucket], arr[j]);
            }

            int pos = 0;
            for (int[] bucket : counter) {
                for (int value : bucket) {
                    arr[pos++] = value;
                }
            }
        }

        return arr;
    }
    /**
     * Automatically expand capacity and save data
     *
     * @param arr
     * @param value
     */
    private int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}

Interviewer: OK, what about bucket sorting? Can you tell me about it?

ABBA ABBA: absolutely. Bucket sort or so-called box sort is a sort algorithm. Its working principle is to divide the array into a limited number of buckets. Each bucket is sorted individually (it is possible to use another sorting algorithm or continue to use bucket sorting recursively). It is used when selecting data sets with special data range for sorting. For example, there is a group of data, such as: [1,2,1,3,5,3,2,1,2,3,4,5,2,1]. Since this part of data is concentrated between 1-5, you need to create 5 buckets, and then put the elements into the matching bucket: put element 1 into bucket 1, and element 2 into bucket 2

ABBA ABBA: put the elements into the matching bucket.

ABBA ABBA: then take these elements out of the bucket in turn, and you'll be in order.

Interviewer: that's right. Make bucket sorting clear. It seems that bucket sorting is suitable for the sorting of data sets with small span in the data set.

ABBA ABBA: Yes, the bucket sort is suitable for

Sort the scores of college entrance examination students in a single subject. The scores are generally 0-100. At this time, establish 100 buckets, and then sort these scores.

The hospital needs to sort the patients according to their age, generally 0-150. At this time, establish 150 barrels, and then sort the patients according to their age.

//Bucket sorting
 public class BucketSort {
 
    private int[] bucketSort(int[] arr, int bucketSize) throws Exception {
        if (arr.length == 0) {
            return arr;
        }

        int minValue = arr[0];
        int maxValue = arr[0];
        for (int value : arr) {
            if (value < minValue) {
                minValue = value;
            } else if (value > maxValue) {
                maxValue = value;
            }
        }

        int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1;
        int[][] buckets = new int[bucketCount][0];

        // The mapping function is used to allocate the data to each bucket
        for (int i = 0; i < arr.length; i++) {
            int index = (int) Math.floor((arr[i] - minValue) / bucketSize);
            buckets[index] = arrAppend(buckets[index], arr[i]);
        }

        int arrIndex = 0;
        for (int[] bucket : buckets) {
            if (bucket.length <= 0) {
                continue;
            }
            // Sort each bucket. Insert sort is used here
            bucket = insertSort.sort(bucket);
            for (int value : bucket) {
                arr[arrIndex++] = value;
            }
        }
        
        return arr;
    }

    /**
     * Automatically expand capacity and save data
     * @param arr
     * @param value
     */
    private int[] arrAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }

}

ABBA ABBA:

Interviewer: I didn't expect you to be so familiar, so let's talk about the quick row


ABBA ABBA: the quick sort algorithm realizes sorting through multiple comparisons and exchanges. The sorting process is as follows
(1) First, set a boundary value, and divide the array into left and right parts through the boundary value.
(2) Collect data greater than or equal to the boundary value to the right of the array, and data less than the boundary value to the left of the array. At this time, all elements in the left part are less than or equal to the boundary value, while all elements in the right part are greater than or equal to the boundary value.
(3) Then, the data on the left and right can be sorted independently. For the array data on the left, you can take another boundary value and divide this part of the data into left and right parts. Similarly, place the smaller value on the left and the larger value on the right. The array data on the right can also be processed similarly.
(4) By repeating the above process, we can see that this is a recursive definition. After the left part is sorted recursively, the right part is sorted recursively. When the sorting of the data in the left and right parts is completed, the sorting of the whole array is completed.

If a set of data needs to be sorted: [31,33,46,12,17]

ABBA ABBA: first select the reference value. Here, 31 is selected

ABBA ABBA: then traverse to the right from the first element after the benchmark value to find a number greater than the benchmark value, and traverse to the left from the last element to find a number less than the benchmark value.

ABBA ABBA: exchange these two elements.

ABBA ABBA: continue to traverse to the right to find a number greater than the benchmark value, and traverse to the left from the last element to find a number less than the benchmark value.

ABBA ABBA: continue to exchange according to the rules

ABBA ABBA: the result is shown in the figure below

ABBA ABBA: finally, put the standard value at the last running position of the "pointer" on the right, so that the number on the left of the benchmark value is less than or equal to the benchmark value, and the number on the right of the benchmark value is greater than or equal to the benchmark value

ABBA ABBA: this round is over. There will be recursion in the fast row, so each element can finally find its own position

ABBA ABBA: the following code is implemented by installing this logic.

public class QuickSort{

  public static void quickSort(int[] arr, int left, int right) {
        if (left >= right) return;;
        // Returns the subscript of the reference value, and then recurses the arrays to the left and right of the reference value
        int j = handler(arr, left, right);
        //Recursive reference value left array
        quickSort(arr,0, j - 1);
        //Recursive reference right array
        quickSort(arr,j + 1, right);
    }


    public static int handler(int[] arr, int start, int end) {
        // Define the left and right sides to find the number on the left that is greater than the benchmark value and the number on the right that is less than the benchmark value
        int left = start;
        int right = end;
        int bound = arr[start];

        while (left < right) {
            //Keep looking until you find it or cross the line
            while(left < right && arr[left] <= bound) left++;
            while(left <= right && arr[right] >= bound) right--;
            // The values found on the left interact with the values found on the right
            if (left < right) {
                int temp = arr[left];
                arr[left] = arr[right];
                arr[right] = temp;
            }
        }
        // This step is critical to locate the position of the reference value
        int temp = arr[start];
        arr[start] = arr[right];
        arr[right] = temp;
        return  right;
    }

}

ABBA ABBA: go through the whole process again.

Interviewer: OK, come to work tomorrow 😈

Algorithm is an essential part of the interview, and the sorting algorithm is asked relatively frequently, so you need to master the basic sorting algorithm. In addition, some questions in leetcode also have the thinking of sorting algorithm. Here are some algorithm questions about sorting in leetcode.

reference resources https://www.runoob.com/

/Thank you for your support/

The above is all the content of this sharing. I hope it will help you^_^

If you like, don't forget to share, like and collect~

Welcome to official account occupation bus, the three brothers from bytes, shrimp skins and silver merchants, sharing programming experience, technical dry cargo and career planning, helping you to walk in the big factory without any detours.

Posted by darf on Wed, 10 Nov 2021 04:59:43 -0800