Algorithm Series 2 Basic Sorting

In basic sorting, we introduce two sorting methods: 选择排序and 插入排序.

Both sorting methods are very simple to implement and understand. Learning them is very helpful for the weaknesses of basic sorting, and understanding why there are advanced sorting algorithms. So, basic does not mean useless. Moreover, insertion sort is often used to optimize the sorting of small arrays for quick sorting. For this, please refer to the previous blog " Quick Sort, One of Algorithm Series ".

selection sort

Selection sort is the easiest method to think of and the easiest to practice in the human mind:

  1. Traverse the entire array, find the smallest value, and put it in the first position of the array.
  2. Starting from the second number, traverse the entire array, find the smallest value, and put it in the second position.
  3. And so on until the entire array is sorted

Selection sort is a very characteristic algorithm. It has two distinctive features:

  1. It does not depend on the case of the input. The algorithm takes the same amount of time to input an inverted array as it is to input a sorted array.
  2. Movement of data is minimal, and each swap changes two values ​​in the array. Therefore, N swaps are used, that is, the number of swaps increases linearly with the length of the array.

The algorithm is implemented as follows:

void selection_sort(int *a, int lo, int hi){

    for( int i = lo; i <= hi; i++){
        int min = i;
        for(int j = i+1; j <= hi; j++) if(a[j] < a[min]) min = j;
        swap(a, i, min);
    }
}

Insertion sort

Insertion sort is the same as selection sort. It maintains an index. All elements to the left of the index are ordered. The difference is that the elements to the left of the index of insertion sort are ordered but their positions are not fixed. If there are smaller elements, they will be inserted into between elements. When the index is moved to the far right, the entire array is in order.

The biggest difference between insertion sort and selection sort is that it depends on the input data . It is much faster if the input is in order (or nearly in order) than out of order (nearly reversed).

void insertion_sort(int *a, int lo, int hi){

    for(int i = lo; i <= hi; i++){
        // 每次处理 第 i个 元素,向左遍历,将其放到合适的位置
        for(int j = i; j >= lo && a[j] < a[j-1]; j--) swap(a, j, j-1);
    }
}

The above implementation is a standard implementation, but in fact, adding some simple changes can improve performance. For example: every time we process an element (let's say v ), it will be swapped with the element on the left that is larger than it, which requires two visits to the array. If we just move the larger element backwards, wait until the position of v is determined, and then put it into the array, then the number of array accesses will be cut in half.

void insertion_sort_better(int *a, int lo, int hi){

    for(int i = lo+1; i <= hi; i++){
        int v = a[i];
        int j = i;
        for(; j >= lo && v < a[j-1]; j--)
            a[j] = a[j-1]; // 每次只移动元素,而不是交换
        a[j] = v; // 最后位置确定时,将元素放入最终位置
    }
}

The more general case where insertion sort works is: partially sorted arrays. In an array like this:

  • Each element is not far from its final position
  • Element inversion (the previous element is greater than the next element) is rare
  • Only a few places are wrong

In such cases, insertion sort is faster than any other sort. So that's why insertion sort is used to handle quicksort of small arrays.


Please indicate the author and source ( reposkeeper ) for reprinting, please do not use for any commercial purposes!

Follow the WeChat public account to get the push of new articles!
qrcode

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324893661&siteId=291194637