Algorithm | Hill Sort

Before understanding Hill sort, be sure to understand  insertion sort first , this is the premise!

The idea of ​​insertion sort is to select the first element in an unsorted array, find a suitable position in the sorted array and insert it. Its advantage over selection sort is that if the array is partially ordered, or most elements are logically The final positions are not too far away, which can greatly reduce the number of comparisons and exchanges.

But there is such a situation, for example, the smallest element is just at the end of the array, it needs to be compared and exchanged with the adjacent elements in turn, so we need to perform N-1 comparisons and N-1 times to exchange positions, in order to convert the smallest element Move to the other end of the array. This process is close to selection sort. For insertion sort, is there a better way to improve the sorting speed and reduce this movement? The answer is Hill sort

In the process of insertion sort, the comparison and exchange of elements occur in adjacent elements, while the Hill sort can span multiple elements at a time. In the insertion sort, we have a span of 1. In the Hill sort, we The span is h . In fact, Hill sorting is an optimization of insertion sorting. In insertion sorting, we have mentioned three complexity cases of insertion sorting, and insertion sorting is suitable for partial ordering of elements , because partial ordered arrays can be greatly Reduce the number of exchanges and comparisons , then Hill sort is used to build a partially ordered array, so as to prepare conditions for insertion sorting with a smaller span to speed up insertion sorting

In insertion sort, the comparison and exchange of elements occur in adjacent elements, and the operation span is 1. Hill sort is actually repeating the process of insertion sort, but the span starts from h , and then continuously Descending, and finally reduced to 1, when the span is 1 , this is the normal insertion sort.

In other words, Hill sort is an insertion sort with different starting points and spans. In each subarray with a span of h, the insertion sort is performed, and h is constantly getting smaller, and the way to get smaller is h=h/3:


When h=13, insert each subarray with an interval of 13 elements into insertion sort. After the insertion sort of all subarrays with an interval of 13 is completed, according to h=h/3

When h=4, insert each subarray with an interval of 4 elements into insertion sort. After the insertion of all subarrays with an interval of 4, the insertion sort is performed according to h=h/3

When h=1, it is a normal insertion sort

Earlier we said that when the array is partially ordered, the advantage of insertion sort is quite large, and we perform insertion sort with different spans to prepare for insertion sort with a span of 1.

When h is reduced to 1, the array is already partially ordered.

The insertion sort algorithm is implemented as:

public class ShellSort {
    public static void main(String[] args) {
        int[] nums = new int[]{1, 15, 3, 78, 34, 23, 46, 2, 8, 34, 57};
        System.out.println(Arrays.toString(nums));
        sort(nums);
        System.out.println(Arrays.toString(nums));
    }

    public static void sort(int[] arrays) {
        int n = arrays.length;

        int h = 1;
        while (h < n / 3) h = 3 * h + 1;

        while (h >= 1) {

            for (int i = h; i < n; i++) {
                int j = i;
                for (; j >= h; j = j - h) {
                    if (arrays[j] < arrays[j - h]){

                        int temp = arrays[j];
                        arrays[j] = arrays[j-h];
                        arrays[j -h] = temp;
                    }
                }
            }

            h = h / 3;
        }


    }
}

In fact, the performance of the above writing method is not high, and the real Hill sort should be as follows:

    public static void sort(int[] arrays) {
        int n = arrays.length;

        int h = 1;
        while (h < n / 3) h = 3 * h + 1;

        while (h >= 1) {

            for (int i = h; i < n; i++) {

                for (int j = i; j >= h && arrays[j] < arrays[j - h]; j = j - h) {

                    int temp = arrays[j];
                    arrays[j] = arrays[j - h];
                    arrays[j - h] = temp;
                }
            }

            h = h / 3;
        }

    }

Put the conditional comparison statement inside the for loop!

The process of Hill sorting is:


The highlighted elements in the figure are the elements that undergo comparison and exchange operations, which can be compared with ordinary insertion sort .

So far, there has been no large-scale data sorting performance verification for selection sort, insertion sort, and Hill sort.

Guess you like

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