“This is the fifth day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

Java language is used for the purpose of the competition, and js/ TS version will be updated later.

Basic introduction

  • Internal sorting
    • All data that needs to be processed is loaded into internal memory for sorting.
    • classification
      • Insertion sort
        • Direct insertion sort (stable, takes no extra space, O(n2))
        • Hill sort (unstable, takes no extra space, O(nlogn))
      • Selection sort
        • Simple selection sort (unstable, takes no extra space, O(n2))
        • Heap sort (unstable, takes no extra space, O(nlogn))
      • Exchange sort
        • Bubble sort (stable, takes no extra space, O(n2))
        • Quick sort (unstable, takes no extra space, O(nlogn))
      • Merge sort (stable, taking up extra space, O(nlogn))
      • Radix sort (buckets sort) :(stable, takes up extra space, O(n* number of buckets))
  • External sorting

Time complexity

  • methods
    • Ex post statistical method
    • Ex ante estimation method
  • Time frequency T(n) : The number of executions of statements in an algorithm
    • Algorithm call time is proportional to the number of statements executed in the algorithm
  • Time complexity O(n
    • If T(n) is different, O(n) might be the same
    • Common time complexity
      • 1, log2n, n, nlog2n, n2, n3, nk, 2n, n!
  • Average time complexity
  • Worst time complexity

Spatial complexity

The storage space consumed by the algorithm

Relevant concepts

  • Stable: does not change the relative position after sorting, for example, a= B, a was before B, after sorting still before B
  • unstable
  • Internal sort: All sort operations take place in memory
  • External sort: A large amount of data is stored in disks, requiring data transfer between disks and memory

Bubble sort

Compare the values of adjacent elements from front to back, and find that reversing the exchange causes the larger values to gradually move from front to back.

  • The rules

    • We loop through the array size -1 times
    • The number of sequences per trip is gradually decreasing
    • If we find that no swap has occurred in a particular sort, we can end the sort early (optimization)
public static void bubbleSort(int[] arr) {
    int temp = 0; // Temporary variables
    boolean flag = false; // Identifies the variable, indicating whether sorting has been done
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                flag = true;
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp; }}/ / optimization point
        if(! flag) {// In a sort. Not a single exchange has occurred, which means it's in order
            break;
        } else {
            // Reset the flag for next judgment
            flag = false; }}}Copy the code

Selection sort

Select an element according to the specified rules, and then swap positions according to the specified to achieve the purpose of sorting.

  • The rules

    • There are n minus 1 rounds of sorting
    • Assume that the current number is the smallest, and compare from each subsequent number once
    • If a smaller number is found, redetermine the minimum number and get the subscript
    • After iterating through this array, swap
    • Then narrow it down and repeat the process
public static void selectSort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[minIndex]) {
                // If it is not the minimum, record the minimum subscriptminIndex = j; }}// Find min subscript changed
        if(minIndex ! = i) {inttemp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; }}}Copy the code

Insertion sort

The element to be sorted is inserted to find the appropriate position of the element, so as to achieve the purpose of sorting

public static void insertSort(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        int insertVal = arr[i]; // Store the values to be inserted
        int index = i - 1; // The index of the number to be inserted that precedes the sorted array
        while (index >= 0 && arr[index] > insertVal) {
            // Move the number of the position back
            arr[index + 1] = arr[index];
            // Keep looking ahead
            index--;
        }
        // Determine whether to insert
        if (index + 1! = i) {// When exiting the loop, the insertion position has been found
            arr[index + 1] = insertVal; }}}Copy the code

Problems: When the number to be inserted is relatively small, the number of backward moves increases significantly, which affects the efficiency

Hill sorting

Reduced increment sort

// Switch method (inefficient)
public static void shellSort(int[] arr) {
    int temp = 0;
    // Get gap: step size, group number
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        // The gap position is the second element of the first group. Each time the gap increases by 1, switch a group and compare with the previous group one by one
        for (int i = gap; i < arr.length; i++) {
            // Compare forward, and the range of comparisons expands until the entire group
            for (int j = i - gap; j >= 0; j -= gap) {
                // If the current element is larger than the element with the added step, swap
                if (arr[j] > arr[j + gap]) {
                    temp = arr[j];
                    arr[j] = arr[j + gap];
                    arr[j + gap] = temp;
                }
            }
        }
    }
}
​
/ / insert method
public static void shellSort2(int[] arr) {
    // Get the step size
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        // Insert sort directly from the gap element, one by one
        for (int i = gap; i < arr.length; i++) {
            // The subscript and value of the current element to be inserted
            int index = i;
            int value = arr[index];
            if (arr[index] < arr[index - gap]) {
                while (index - gap >= 0 && arr[index] < arr[index - gap]) {
                    arr[index] = arr[index - gap];
                    index -= gap;
                }
                // Find the position, break out of the loop, and assignarr[index] = value; }}}}Copy the code

Quick sort

The improvement of bubble sort, the basic idea: through a sort will be sorted into separate two parts of the data, one part of the data is smaller than the other part of the data, and then according to the sub-method of quick sort respectively. Procedures run recursively

// Quicksort
public static void quickSort(int[] arr, int left, int rigth) {
    int l = left;/ / left subscript
    int r = rigth;/ / right subscripts
​
    // The value of the pivot
    int pivot = arr[(rigth + left) / 2];
    int temp = 0;// temp temporary variables are referenced at swap time
​
    // While purpose:
    // 1. Place the value smaller than pivot to the left
    // 2. Place the value greater than pivot on the right
    while (l < r) {// Premise: The left side is always less than the right side
        // Keep looking to the left of pivot until the value is greater than or equal to the pivot value
        while (arr[l] < pivot) {
            l += 1;// or l++, but it seems inefficient to increment after, because you still end up with l=l+1 and l+=1
        }
        // Keep looking to the right of the pivot until the value is less than or equal to the pivot value
        while (arr[r] > pivot) {
            r -= 1;
        }
​
        // If l >= r then the values on both sides of pivot follow the rule:
        // The left is all less than or equal to pivot, and the right is all greater than or equal to pivot.
        if (l >= r) {
            break;
        }
​
        / / exchange
        temp = arr[l];
        arr[l] = arr[r];
        arr[r] = temp;
​
        Arr [l] = arr[pivot] = arr[pivot] = arr[pivot] = arr[pivot
        if (arr[l] == pivot) {
            r -= 1;
        }
        // if arr[r] = arr[pivot] = arr[pivot], then l++ will be changed
        if (arr[r] == pivot) {
            l += 1; }}// if l==r, l++, r-- otherwise, the stack overflows in an infinite loop
    if (l == r) {
        l += 1;
        r -= 1;
    }
​
    // Recurse to the left
    if (left < r)
        quickSort(arr, left, r);
    // Recursive to the right
    if (rigth > l)
        quickSort(arr, l, rigth);
}
Copy the code

Merge sort

Adopt the idea of divide and conquer

public class MergeSort {
    public static void main(String[] args) {
        int[] arr = {8.4.5.7.1.3.6.2};
        int[] temp = new int[arr.length];
        mergeSort(arr, 0, arr.length - 1, temp);
        System.out.println(Arrays.toString(arr));
    }
​
    public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if (left < right) {
            int mid = (left + right) / 2; // Intermediate index
            mergeSort(arr, left, mid, temp);
            mergeSort(arr, mid + 1, right, temp);
            // Mergemerge(arr, left, mid, right, temp); }}// Merge methods
    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left; // Initialize I, the initial index of the left ordered sequence
        int j = mid + 1; // initialize j, the initial index of the ordered sequence on the right
        int t = 0; // Specify the current index of temp array
​
        // Fill the left and right sides (ordered) into the temp array
        // Until one of the ordered sequences on the left and right sides is processed
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            } else{ temp[t++] = arr[j++]; }}// Fill all remaining data into temp in turn
        while (i <= mid) {
            temp[t++] = arr[i++];
        }
​
        while (j <= right) {
            temp[t++] = arr[j++];
        }
        // Copy the elements of the temp array to arR
        // Note that not all copies are made every time
        t = 0;
        int tempLeft = left;
        while(tempLeft <= right) { arr[tempLeft++] = temp[t++]; }}}Copy the code

Radix sort

Stability, the most efficient stability sorting method

Problem: Space

An array with negative numbers is sorted without using radix sort

// Base sort
public static void radixSort(int[] arr) {
​
    // Calculates the largest number of digits in the array
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if(arr[i] > max) { max = arr[i]; }}// Get the maximum number of digits
    int maxLength = (max + "").length();
    int[][] bucket = new int[10][arr.length];
​
    // To record each bucket, store the number of buckets
    int[] bucketElementCounts = new int[10];
​
    for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
        for (int j = 0; j < arr.length; j++) {
            // Fetch the value of the corresponding bit of each element
            int digitOfElement = arr[j] / n % 10;
            // Put the bucket into the corresponding bucket, then the corresponding amount ++
            bucket[digitOfElement][bucketElementCounts[digitOfElement]++] = arr[j];
        }
​
        int index = 0;
        for (int k = 0; k < bucketElementCounts.length; k++) {
            if (bucketElementCounts[k] > 0) {
                // If there is data in the bucket, it is added to the original array
                for (int t = 0; t < bucketElementCounts[k]; t++) {
                    // Take the element and put it into arRarr[index++] = bucket[k][t]; }}// After I +1, I need to clear 0
            bucketElementCounts[k] = 0; }}}Copy the code