Algorithm - C language implements Shell sort (Shell_sort)

Table of contents

What is Hill sort?

Hill sort usage scenarios:

Introduce Hill sort by comparison between sorts:

Demonstrate the process of Hill sorting:

Sort the first pass:

Second sorting:

The third sort:

The fourth sort:

Program Verification:

code:

Hill sorting in real life:

Summary of Hill sort:


What is Hill sort?

Before writing the code for Hill sorting, let's sort out the sorting principle and definition of Hill sorting:

Shell's sort, also known as shrinking incremental sorting, is a method belonging to the insertion sorting category, but it has a greater improvement in time efficiency than the aforementioned total sorting method. The basic idea of ​​Hill sorting is: first divide the entire sequence of records to be sorted into several word sequences and perform direct insertion sorting respectively, and then perform a direct insertion sorting on all records when the records in the entire sequence are "basically in order".

Hill sorting is equivalent to the optimization of insertion sorting. As mentioned in my previous article C language implementation of insertion sorting , insertion sorting is a sorting in which a part of the sequence is already in order. Insertion sorting The more orderly, the higher the efficiency .

Hill sort usage scenarios:

Hill sorting is suitable for sorting medium-sized data volumes.

Introduce Hill sort by comparison between sorts:

For example here we are given a sequence:

int ar[5] = {1,2,3,4,0};

 If we use bubble sorting at this time, the total number of times that need to be executed is four times, until the element 0 is placed at the front, and the execution order of each time is:

{1,2,3,0,4};
{1,2,0,3,4};
{1,0,2,3,4};
{0,1,2,3,4};

But if we use insertion sort, the efficiency will be greatly improved, and element 0 can be placed at the front only once. 

We first scan the array until the subscript scans to the 0th element, which does not satisfy the rule that the latter is greater than the former. At this time, we assign 0 to temp, and now compare it with the previous sorted sequence. 0 is better than any of them. It should be small, so the elements 1, 2, and 3 are moved backward one bit, and 0 is placed at the front.

{0,1,2,3,4};

Let's go back to Hill sorting. Hill sorting is equivalent to the optimization of insertion sorting. Although insertion sorting has obvious advantages over bubble sorting and selection sorting, when there are a large number of elements in the sequence that need to be sorted, each time It is a bit complicated to compare with adjacent elements every time, and Hill sorting is designed to solve this complexity.

Demonstrate the process of Hill sorting:

As shown in the figure, I give an array:

{10,11,13,5,0,13,2,7,8,6,0};

Sort the first pass:

Next, we demonstrate the process of Hill sorting on the drawing board:

Second sorting:

Define the sorting increment as the length of the entire sequence, and compare it directly. We found that 10 > 0, so the positions of the two elements are swapped, and the sorting increment is reduced to half of the original in the next sorting:

Because I define the gap value in the form of an integer value, the number of elements is 11, and 11 / 2 is 5.5. Here, the gap value is directly taken as 5, and we find that 11 > 2, 13 > 7, 13 > 10, Therefore, the positions of these six elements are exchanged. The lower part of the figure is the order of the elements after the second sorting: 0 2 7 5 0 10 11 13 8 6 13.

The third sort:

At this time, the value of gap becomes half of the second time: 5 / 2 = 2.5, here the value of gap is 2:

We found that: 7 > 0, 13 > 11 > 8, the positions of these six elements are exchanged, and the lower part of the figure is the element after the third sorting: 0 2 0 5 7 6 8 10 11 13 13

The fourth sort:

At this time, the value of gap becomes one, which is equivalent to direct insertion sorting. The result of the fourth sorting is also the final sorting result. We found: 2 > 0, 7 > 6, we swap the positions of these four elements, and sort The final result is: 0 0 2 5 6 7 8 10 11 13 13

Program Verification:

As shown in the figure, the 11 numbers are successfully sorted.

code:

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#define MAXSIZE 11
void initar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		ar[i] = rand() % 20;
	}
}
void showar(int *ar,int len)
{
	assert(ar != nullptr);
	for(int i = 0;i < len;i++){
		printf("%d ",ar[i]);
	}
	printf("\n--------------------------\n");
}
void Shell_sort(int *ar, int len) {
	assert(ar != nullptr && len >= 0);
	int i = 0,j = 0;
	int temp = 0;//定义中间值用于存储数据
	int gap = 0;//定义排序增量
	gap = len;//将排序增量的初始值直接设置为数组的长度
	while(gap > 1){
		gap /= 2;
		for(i = gap;i < len;i += gap){
			if(ar[i] < ar[i - gap]){
				temp = ar[i];
				for(j = i - gap;j >= 0 && ar[j] > temp;j -= gap){
					ar[j + gap] = ar[j];
				}
				ar[j + gap] = temp;
			}
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));
	int ar[MAXSIZE];
	initar(ar,MAXSIZE);
	printf("原始数据为:\n");
	showar(ar,MAXSIZE);
    printf("\n经过希尔排序后的数据为:\n");
	Shell_sort(ar,MAXSIZE);
	showar(ar,MAXSIZE);
}

Using the 12 numbers less than 20 randomly generated by the computer, let's use Hill sorting for sorting. I added a display array statement at the end of the third layer of the for loop of the function, and the entire array will be output for each sorting pass. We Take a look at the results:

As shown in the figure, I used Hill sort to perform a total of four sorts (that is, the value of the gap changed four times), and finally completed the ascending sort of the data randomly generated by the system. 

Hill sorting in real life:

We have all played poker, even if we haven’t played it, we have seen others play it. Every deck of poker is new when we buy it, and they are sorted according to different suits from small to large. We can put this sorting process Think of it as a simple Hill sort.

Before starting to sort the 54 playing cards from small to large, should we first divide the playing cards into four groups according to different suits, corresponding to: clubs, diamonds, spades, hearts, then we can understand that we The current sorting increment is 4. Next, we will sort the 13 numbers in different suits from small to large. The sorting increment is 1, and the sorting method is direct insertion sorting.

So the sorting of playing cards can be regarded as a simple Hill sorting, the sorting increment changes from 4 to 1, and after two passes, the sorting is finally completed.

Summary of Hill sort:

The time complexity of Hill sorting changes with the sorting increment (gap). The time complexity changes between O(nlogn)~O( ), and the n^{2}space complexity is always O(1). Hill Sorting is an unstable algorithm.

The execution order of Hill sorting is: the sorting increment decreases, and when the increment becomes 1, direct insertion sorting is performed.

Space complexity is O(1): because only temporary variables need to be saved.

Hill sorting is an unstable algorithm: due to the sorting increment, the sequence is divided into different sequences, but this may cause the relative position of the same element to change, such as an odd sequence {4,5,3,2,1}, if If the sorting increment (gap) value at this time is 2, then the relative position of the last element 1 will change.

Guess you like

Origin blog.csdn.net/weixin_45571585/article/details/125975529#comments_27891441