[xsong algorithm] phase I: sorting algorithm

Chapter 1: sorting algorithm

1.1 select sort

Select sort. No matter what data goes in, it is O(N ²) The only advantage is that it does not occupy additional storage space

Algorithm ideas and steps

First, find the largest (small) element, store it in the starting position, and repeatedly find the smallest one back until all elements are sorted

  • The following is a code demonstration:
    /**
     * Use selection sorting to solve problems
     *
     * @param nums array
     * @return Returns a sorted array
     */
    public int[] sortArray(int[] nums) {
        //Subscript of minimum value
        for (int i = 0; i < nums.length ; i++) {
            int min = i;
            for (int j = i; j < nums.length; j++) {
                if (nums[j] < nums[min]) {
                    min = j;
                }
            }
            if (min != i) {
                int temp = nums[i];
                nums[i] = nums[min];
                nums[min] = temp;
            }
        }
        return nums;
    }

Advantages of selective sorting: minimum number of exchanges

"Selective sorting" seems to be the most useless, but it can be used in sorting tasks with high exchange cost (after class exercises in relevant chapters of algorithm 4).

Don't be personal about the algorithm. When answering questions in an interview and looking at a person and thing, the answer mode you can refer to is "specific analysis of specific questions, under what circumstances, what algorithm to use".

1.2 bubble sorting

Fastest: when the input data is already in positive order (I also want you to bubble sorting)

Slowest: when the input data is in reverse order (why use your bubble sorting? Am I free).

Algorithm ideas and steps

Each time the adjacent elements are compared, if the first one beats the second one, they are exchanged directly until there is no pair of numbers to compare

  • The following is a code demonstration
     /**
         * Using bubble sorting to solve problems
         *
         * @param nums array
         * @return Returns a sorted array
         */
        public int[] sortArray(int[] nums) {
            boolean mark = true;
            while (mark) {
                boolean end = false;
                for (int i = 0; i < nums.length - 1; i++) {
                    if (nums[i] > nums[i + 1]) {
                        int temp = nums[i];
                        nums[i] = nums[i + 1];
                        nums[i + 1] = temp;
                        end = true;
                    }
                }
                mark = end;
            }
            return nums;
        }
    
  • More official answers
        public int[] sortArray(int[] nums) {        
            int len = nums.length;
            for (int i = len - 1; i >= 0; i--) {
                // First, the default array is ordered. As long as an exchange occurs, the next round of comparison must be carried out
                boolean sorted = true;
                for (int j = 0; j < i; j++) {
                    if (nums[j] > nums[j + 1]) {
                        swap(nums, j, j + 1);
                        sorted = false;
                    }
                }
    
                // If no exchange operation is performed in the inner loop, the array is already in ascending order
                if (sorted) {
                    break;
                }
            }
            return nums;
        }
        private void swap(int[] nums, int index1, int index2) {
            int temp = nums[index1];
            nums[index1] = nums[index2];
            nums[index2] = temp;
        }
    

1.3 insert sort

Like bubble sort, insertion sort also has an optimization algorithm called split half insertion.

Algorithm solving steps:

Default to the first order, and then compare it from back to front until you can't find one smaller than yourself, and then insert it

  • Algorithm implementation:
    /**
     * Using insert sort to solve problems
     *
     * @param nums array
     * @return Returns a sorted array
     */
    public int[] sortArray(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            int temp = nums[i];
            int j = i;
            while(j>0 && temp<nums[j-1]){
                nums[j] = nums[j-1];
                j--;
            }
            if(j != i){
                nums[j] =temp;
            }
        }
        return nums;
    }

1.4 Hill sorting

Hill sort is a more efficient improved version of direct insertion sort algorithm. Hill sort is an unstable sort algorithm

1.5 merge sort

The algorithm is a very typical application of Divide and Conquer.

Algorithm solving steps:

The core of merge sort is recursion. We need to sort the left and right parts of the array respectively, and then combine the left and right ordered arrays to form an ordered array

  • Code demonstration:
/**
 * @author song
 * Merge sort sorts an array
 */
public class Code02_MerageSort {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 5, 1, 4, 9, 7};
        process(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    public static void process(int[] arr, int L, int R) {
        if (L == R) {
            return;
        }
        int mid = L + ((R - L) >> 1);
        process(arr, L, mid);
        process(arr, mid + 1, R);
        merage(arr, L, mid, R);
    }

    public static void merage(int[] arr, int L, int M, int R) {
        int[] help = new int[R - L + 1];
        int i = 0;
        int p1 = L;
        int p2 = M + 1;
        //It means that there are several intervals on the left and right
        while (p1 <= M && p2 <= R) {
            help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }
        //There are only a few on the left
        while (p1 <= M) {
            help[i++] = arr[p1++];
        }
        //Similarly, there are only a few on the right
        while (p2 <= R) {
            help[i++] = arr[p2++];
        }
        for (int j = 0; j < help.length; j++) {
            arr[L + j] = help[j];
        }
    }
}

****ps: there is a classic example LeetCode sword finger offer51 I suggest you do this question every time you review the merging and sorting [when doing this question, the core part must be careful when judging the critical value]

1.6 quick sort

The worst case for quicksort is O(n) ²), For example, the fast sorting of sequential sequences. But its expected spreading time is O(nlogn), and the constant factor implicit in the O(nlogn) sign is very small, which is much smaller than the merging sorting with stable complexity equal to O(nlogn). Therefore, for most random sequences with weak ordering, fast sorting is always better than merging sorting.

Algorithmic thought

  1. Pick an element from the array and call it a pivot
  2. Reorder. The smaller than the benchmark is in front of the benchmark, and generally refers to the larger than the benchmark
  3. Recursion, taking the benchmark as the standard, the numbers on the left and right sides execute one or two steps respectively
  • code implementation
import java.util.Random;

public class Solution {

    // Quick sort 3: three pointer quick sort

    /**
     * If the list size is equal to or less than this size, insert sorting will take precedence over quickSort
     */
    private static final int INSERTION_SORT_THRESHOLD = 7;

    private static final Random RANDOM = new Random();

    public int[] sortArray(int[] nums) {
        int len = nums.length;
        quickSort(nums, 0, len - 1);
        return nums;
    }

    private void quickSort(int[] nums, int left, int right) {
        // Intercell insertion sorting
        if (right - left <= INSERTION_SORT_THRESHOLD) {
            insertionSort(nums, left, right);
            return;
        }

        int randomIndex = left + RANDOM.nextInt(right - left + 1);
        swap(nums, randomIndex, left);

        
        int pivot = nums[left];
        int lt = left;
        int gt = right + 1;

        int i = left + 1;
        while (i < gt) {
            if (nums[i] < pivot) {
                lt++;
                swap(nums, i, lt);
                i++;
            } else if (nums[i] == pivot) {
                i++;
            } else {
                gt--;
                swap(nums, i, gt);
            }
        }
        swap(nums, left, lt);
        // Note here that the partition interval on both sides is greatly reduced
        quickSort(nums, left, lt - 1);
        quickSort(nums, gt, right);
    }

    /**
     * Insert sort is used for the sub interval [left, right] of array num
     *
     * @param nums  Given array
     * @param left  Left boundary, can you get it
     * @param right Right boundary, you can get it
     */
    private void insertionSort(int[] nums, int left, int right) {
        for (int i = left + 1; i <= right; i++) {
            int temp = nums[i];
            int j = i;
            while (j > left && nums[j - 1] > temp) {
                nums[j] = nums[j - 1];
                j--;
            }
            nums[j] = temp;
        }
    }

    private void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }
}

LeetCode actual combat

Tags: Java Algorithm HashMap

Posted on Sat, 27 Nov 2021 21:35:17 -0500 by DeepakJ