Interview site: Shredded Fast Sorting Algorithm

Algorithm Overview

Quick sort (Quicksort), also known as division exchange sort , referred fast row A sorting algorithm, first proposed by Tony Hoare. Under average conditions, to sort n items to O (n log n) comparisons. In the worst situation you need to O (n ^ 2) comparisons, but this situation is not uncommon.

In fact, the quick sort O (n log n) generally significantly faster than other algorithms, because its inner loop can be effective in reaching on most architectures.

Algorithmic process

Quick sort using a divide and conquer strategy to put into a sequence of smaller and larger two sub-sequence, and then sort recursively two sequences.

Steps:

  1. Selection reference value: pick an element from the series, called "reference" (Pivot),
  2. Segmentation: reordering columns, all smaller than the reference value is placed in front of the reference element, all larger than the reference value elements placed behind the reference (equal to the reference value can be any number of side). After the end of this split, sort of reference values ​​has been completed,
  3. Recursive sorting sequence: recursively to a value smaller than the reference sequence element is greater than the reference value of the ordered sequence of elements.

The bottommost recursive determination condition is the size of the number of columns or a zero, at which time the number of columns apparently ordered.

Select reference value several kinds of specific methods, this selection method has a decisive influence on the performance of the time ordered.

Quick sort code logic may be expressed as:

public void quick(int arr, int head, int tail) {
    /*
    * 1.递归终止条件
    * 2.定义头尾指针与基准值
    * 2.把小于基准数的移到左边,把大于基准数的移到右边
    */
    quick(arr, head, right); //继续处理左边的
    quick(arr, left, tail); //继续处理右边的
}

Sample Code

public class QuickSort {
  
    public static void qSort(int[] arr, int head, int tail) {
        if (head >= tail || arr == null || arr.length <= 1) {
            return;
        }
        //定义俩指针 用于移动
        int left = head;
        int right = tail;
        int pivot = arr[head]; //基准值,也可以arr[(head + tail) / 2]

        while (left <= right) {
            while (arr[left] < pivot) { //左指针先走,找到大于等于基准数的停止
                ++left;
            }
            while (arr[right] > pivot) { //右指针后走,找到小于等于基准数的停止
                --right;
            }
            if (left < right) {
                //交换arr[left]和arr[right]的位置
                int t = arr[left];
                arr[left] = arr[right];
                arr[right] = t;
                //继续遍历
                ++left;
                --right;
            } else if (left == right) {
                //遍历完,错开两指针
                ++left;
                //break;
            }
        }

        qSort(arr, head, right);
        qSort(arr, left, tail);
    }

    public static void main(String[] args) {
        int[] arr = new int[]{6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
        qSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
  
}

Printout:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In the program operation, the process may be run through the column was observed before the number of prints ordered and sorted

对数组 [6 1 2 7 9 3 4 5 10 8 ] 排序, 排序后 [5 1 2 4 3 9 7 (6) 10 8 ] 
对数组 [5 1 2 4 3 ] 排序, 排序后 [3 1 2 4 (5) 9 7 6 10 8 ] 
对数组 [3 1 2 4 ] 排序, 排序后 [2 1 (3) 4 5 9 7 6 10 8 ] 
对数组 [2 1 ] 排序, 排序后 [1 (2) 3 4 5 9 7 6 10 8 ] 
对数组 [3 4 ] 排序, 排序后 [1 2 (3) 4 5 9 7 6 10 8 ] 
对数组 [9 7 6 10 8 ] 排序, 排序后 [1 2 3 4 5 8 7 6 10 (9) ] 
对数组 [8 7 6 ] 排序, 排序后 [1 2 3 4 5 6 7 (8) 10 9 ] 
对数组 [6 7 ] 排序, 排序后 [1 2 3 4 5 (6) 7 8 10 9 ] 
对数组 [10 9 ] 排序, 排序后 [1 2 3 4 5 6 7 8 9 (10) ] 

Complexity Analysis

time complexity

Array has n elements, due to the recursive computation, calculates the position of the fulcrum pivot, then a recursive call half and the left half portion, on the understanding that, if this time, then the first layer is n / 2, n / 2, if the second layer is n / 4, n / 4, n / 4, n / 4 four parts, namely the n elements is understood that a total of layers 2 ^ k = n, k = log2 (n), are then each complexity of n, then the average is O (nlog2 n) time complexity. But this is certainly the average case, if you are the sort of standard case, if already in ascending order, then there is only the right half of the recursion, left half have been eliminated. (the n--1) (the n--2) .... 1 *, this is certainly the complexity of O (the n-^ 2) .

Space complexity

Fast discharge is achieved recursive calls, each function call and uses only the spatial constant, and therefore equal to the spatial complexity of the recursion depth.

The best situation requires O (log2 n) nested recursive calls at most times, it requires O (log2 n) space. It requires O (n) time in the worst case of nested recursive calls, requiring O (n) space.

Knowing almost reference time complexity

https://www.zhihu.com/question/22393997/answer/189896378

Guess you like

Origin www.cnblogs.com/yueshutong/p/11369126.html