Data architecture and algorithm-C/C++ implements the Shell Sort algorithm [Recommended collection]

1. Introduction to Hill Sorting

Shell Sort (Shell Sort) is a kind of insertion sort, which is an improvement of the direct insertion sort algorithm. This method is also called reduced incremental sorting, because DL. Shell was named after it was proposed in 1959.

Hill sorting is essentially a grouping insertion method. Its basic idea is: for n numbers to be sorted, take an integer gap smaller than n (gap is called a step size) to divide the elements to be sorted into several group subsequences, and place all records whose distance is a multiple of the gap In the same group; then, the elements in each group are directly inserted and sorted. After this sorting is completed, the elements of each group are in order. Then reduce the value of gap, and repeat the above grouping and sorting. Repeat this operation, when gap=1, the entire sequence is ordered.

Two, Hill sorting graphic description

Hill sort code (1)

/*
 * 希尔排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组的长度
 */
void shell_sort1(int a[], int n)
{
    
    
    int i,j,gap;

    // gap为步长,每次减为原来的一半。
    for (gap = n / 2; gap > 0; gap /= 2)
    {
    
    
        // 共gap个组,对每一组都执行直接插入排序
        for (i = 0 ;i < gap; i++)
        {
    
    
            for (j = i + gap; j < n; j += gap) 
            {
    
    
                // 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。
                if (a[j] < a[j - gap])
                {
    
    
                    int tmp = a[j];
                    int k = j - gap;
                    while (k >= 0 && a[k] > tmp)
                    {
    
    
                        a[k + gap] = a[k];
                        k -= gap;
                    }
                    a[k + gap] = tmp;
                }
            }
        }

    }
}

In the Hill sorting above, first select the value of the step gap. After the gap is selected, the sequence is divided into gap groups, and direct insertion sort is performed for each group. After sorting all the groups, halve the value of gap; continue to group the series, and then sort. Repeat this operation until gap<0. At this time, the sequence of numbers is also in order.

For the convenience of observation, we separate the direct insertion sort in Hill sorting, and get the code (2).

Hill sort code (2)

/*
 * 对希尔排序中的单个组进行排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组总的长度
 *     i -- 组的起始位置
 *     gap -- 组的步长
 *
 *  组是"从i开始,将相隔gap长度的数都取出"所组成的!
 */
void group_sort(int a[], int n, int i,int gap)
{
    
    
    int j;

    for (j = i + gap; j < n; j += gap) 
    {
    
    
        // 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。
        if (a[j] < a[j - gap])
        {
    
    
            int tmp = a[j];
            int k = j - gap;
            while (k >= 0 && a[k] > tmp)
            {
    
    
                a[k + gap] = a[k];
                k -= gap;
            }
            a[k + gap] = tmp;
        }
    }
}

/*
 * 希尔排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组的长度
 */
void shell_sort2(int a[], int n)
{
    
    
    int i,gap;

    // gap为步长,每次减为原来的一半。
    for (gap = n / 2; gap > 0; gap /= 2)
    {
    
    
        // 共gap个组,对每一组都执行直接插入排序
        for (i = 0 ;i < gap; i++)
            group_sort(a, n, i, gap);
    }
}

Let’s take the sequence {80,30,60,40,20,10,50,70} as an example to demonstrate its Hill sorting process.

Round 1: (gap=4)
Insert picture description here
When gap=4, it means that the sequence is divided into 4 groups: {80,20},{30,10},{60,50},{40,70}. Corresponding sequence: {80,30,60,40,20,10,50,70}
Sort these 4 groups separately, the sort result: {20,80},{10,30},{50,60}, {40,70}. Corresponding sequence: {20,10,50,40,80,30,60,70}

Second round: (gap=2)
Insert picture description here
When gap=2, it means that the sequence is divided into 2 groups: {20,50,80,60}, {10,40,30,70}. Corresponding series: {20,10,50,40,80,30,60,70}
Note: {20,50,80,60} actually has two ordered series {20,80} and {50,60 }composition.
{10,40,30,70} actually consists of two ordered sequences {10,30} and {40,70}.
Sort these 2 groups separately, and the sort result: {20,50,60,80}, {10,30,40,70}. Corresponding sequence: {20,10,50,30,60,40,80,70}


Insert picture description here
Third trip: (gap=1) When gap=1, it means that the sequence is divided into 1 group: {20,10,50,30,60,40,80,70}, note: {20,10, 50,30,60,40,80,70} actually consists of two ordered series {20,50,60,80} and {10,30,40,70}. Sort these 1 groups separately, and the sort result: {10,20,30,40,50,60,70,80}

The editor recommends my own linuxC/C++ language technology exchange group: [ 1106675687 ] I have compiled some learning books and video materials that I think are better to share in the group files, and you can add them if you need them!
Insert picture description here

3. Time complexity and stability of Hill sorting

Hill sorting time complexity The time complexity of
Hill sorting is related to the selection of increment (ie, step gap). For example, when the increment is 1, Hill sorting degenerates into direct insertion sorting, and the time complexity at this time is O(N²), while the time complexity of Hibbard incremental Hill sorting is O(N3/2) .

Hill sorting stability
Hill sorting is an unstable algorithm, which satisfies the definition of a stable algorithm. For the same two numbers, their order may change due to being in different groups.
Algorithm stability-suppose there is a[i]=a[j] in the sequence, if before sorting, a[i] is before a[j]; and after sorting, a[i] is still before a[j] . Then this sorting algorithm is stable!

Four, Hill sorting implementation

Hill sort C implementation
实现代码(shell_sort.c)

 View Code

Hill sort C++ implementation
实现代码(ShellSort.cpp)

 View Code

Hill sorting Java implementation
实现代码(ShellSort.java)

View Code

The principles and output results of the above three implementations are the same. Here is their output:

before sort:80 30 60 40 20 10 50 70 
after  sort:10 20 30 40 50 60 70 80 

Guess you like

Origin blog.csdn.net/m0_50662680/article/details/112986479