Insertion sort and Hill sort

Insertion sort

Idea: The idea of ​​insertion sort is to insert the data in an unnecessary sequence into an already ordered sequence one by one, so that the originally ordered sequence is still in order after insertion, and finally the entire sequence is sorted. In the actual sorting process, the "ordered sequence" refers to the part of the sequence that has been sequenced. Consider insertion sort on the following array:


Consider the element 6 first, because the first element 8 has only itself and is already sorted.


When considering 6, insert the element 6 into the ordered part "8", 6 should be in front of 8, so after this step, the array is


Next, consider the element 2. At this time, the ordered part of the array is "8 6", and 2 is inserted into the appropriate position in the ordered part. The result is


The next step is to consider the element 3. At this time, the ordered part of the array is "2 6 8", and the result of inserting 3 into the appropriate position is


The above process is the idea of ​​insertion sort. The algorithm consists of two layers of loops. The outer loop is responsible for traversing the elements of the array, and the inner loop is responsible for finding the appropriate position for the i-th element selected by the outer loop in the ordered part. There are two methods in the process of finding a location for insertion. Consider the penultimate picture above: one is to swap 3 and 8, and then 3 and 6 to complete the insertion sort of 3; the other is to swap 3 For temporary storage, if 8 is larger than 3, move 8 back one position, and continue to judge that 6 is also larger than 3, then move 6 back one position, and continue to judge that 2 is not greater than 3, so insert 3 after 2. Among the two methods, the first one is equivalent to 3 assignment operations per exchange, while the second method is only one assignment, so the efficiency will be higher.

Finally, compared with selection sorting, since the inner loop of selection sorting needs to find the extreme value index of the remaining elements each time, the inner loop needs to be completely executed to end, while the inner loop of insertion sorting, once it finds a suitable position will end early, so it will be more efficient. In fact, for a nearly sorted array, insertion sort is very efficient.

Hill sort

Hill sorting is also an insertion sorting algorithm, which is an improved version of the above insertion sorting algorithm. The complexity of the algorithm breaks through O(n^2).

Idea: Group the array to be sorted for insertion sort, and divide the array elements into several groups by an increment for sorting. Gradually decrease the increment, continuing to sort by group until the increment is 1. It is easier to understand by looking at the picture, the gap is an increment!


Code

sortTestHelper.h

// Created by Boot Hot on 2018/4/19.
//

#ifndef SORT_SORTTESTHELPER_H
#define SORT_SORTTESTHELPER_H

#include <iostream>
#include <ctime>
#include <cassert>

using namespace std;
namespace SortTestHelper {

    int *generateRandomArray(int n, int RangeL, int RangeR) {
        assert(RangeL <= RangeR);
        int *arr = new int[n];
        srand(time(NULL));
        for (int i = 0; i < n; i++) {
            arr[i] = rand() % (RangeR - RangeL + 1) + RangeL;
        }
        return arr;
    }

    template<typename T>
    void printArray(T arr[], int n) {
        for (int i = 0; i < n; i++) {
            cout << arr[i] << ' ';
        }
        cout << endl;
    }

    template<typename T>
    bool isSorted (T arr [], int n) {
        for (int i = 0; i < n - 1; i++) {
            if (arr[i] > arr[i + 1])
                return false;
        }
        return true;
    }

    template<typename T>
    void testSort(string name, void(*sort)(T [], int n), T arr[], int n) {
        clock_t startTime = clock();
        sort(arr, n);
        clock_t endTime = clock();
        assert (isSorted (arr, n));
        cout << name << ": " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
    }

    int *copyIntArray(int a[], int n) {
        int *arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = a[i];
        }

        return arr;
    }

};
#endif //SORT_SORTTESTHELPER_H

main.cpp

#include <iostream>
#include "sortTestHelper.h"
using namespace std;

template<typename T>
void InsertSort(T k[], int len) {
    T temp;  int j;
    for (int i = 1; i < len; i++) {
        if (k[i] < k[i - 1]) {
            temp = k[i];
            for (j = i; j > 0 && k[j - 1] > temp; j--) {
                k[j] = k[j - 1];
            }
            k[j] = temp;
        }
    }
}

template<typename T>
void ShellSort(T k[], int len) {
    for (int gap = len / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < len; i++) {
            int j = i;
            T temp = k[j];
            if (k[j] < k[j - gap]) {
                while (j - gap >= 0 && temp < k[j - gap]) {
                    k[j] = k[j - gap];
                    j -= gap;
                }
                k[j] = temp;
            }
        }
    }
}

int main() {
    int n = 50000;
    int *arr = SortTestHelper::generateRandomArray(n, 0, n);
    int *arr2 = SortTestHelper::copyIntArray(arr, n);
    SortTestHelper::testSort("Insert Sort", InsertSort, arr, n);
    SortTestHelper::testSort("Shell  Sort", ShellSort, arr2, n);

    delete[] arr;
    delete[] arr2;

    return 0;
}

output:

Insert Sort: 3.024 s
Shell  Sort: 0.019 s

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326952301&siteId=291194637