[Data structure] - insertion sort family (direct insertion sort, Hill sort)

Author: A small sapling longs to become a towering tree
Author's declaration: Write every blog carefully
Author gitee: If
insert image description here
you like the author's articles, please pay attention to the author!


foreword

Today we will introduce about insertion sorting. Insertion sorting is divided into two types, one is direct insertion sorting and the other is Hill sorting. These two sortings have similarities, so let’s introduce these two sortings next. (explained in ascending order)


1. Direct insertion sort

Let's take a look at the animation demonstration first:
insert image description here
we are walking backward step by step, moving one bit to the back when we encounter a large one, and inserting data to the back of the small one when we know that we have encountered a small one. Let's take a look at the single-pass sort first:

	int end = 9;
		int key = a[end];//先把要插入的数据保存起来,方便和其他数进行比较
		while (end >= 0)
		{
    
    
			if (key < a[end - 1])//可以小于前面的数,就把数往后面移一位
			{
    
    
				a[end] = a[end - 1];//
				  end--;
			}
			else//比前面a[end-1]的这位大就退出,把数据放到它后面,就是a[end]的位置
			{
    
    
				break;
			}
		}
		a[end] = key;//把要插入的数放到这个位置

Single-pass sorting results:
insert image description here

Let's look at the drawing:
insert image description here

In actual sorting, when the last digit starts to be sorted, the front should be in order. We will select the key from the front to the back to insert, but the idea of ​​each trip is the same.

Let's take a look at the complete sort:

void insertsort(int* a, int n)
{
    
    
	for (int i = 1; i <= n-1; i++)//i从1开始就可以了,没必要从0开始
	{
    
    
		int end = i;
		int key = a[end];//先把要插入的数据保存起来,方便和其他数进行比较
		while (end > 0)//因为都是和前面的数进行,加等于就跳到前面的位置,越界了,
		{
    
    
			if (key < a[end - 1])//可以小于前面的数,就把数往后面移一位
			{
    
    
				a[end] = a[end - 1];//把前面大的数移到后一位
			   end--;
			}
			else//比前面a[end-1]的这位大就退出,把数据放到它后面,就是a[end]的位置
			{
    
    
				break;
			}
		}
		a[end] = key;//把要插入的数放到这个位置
	}
}

After everyone has mastered this idea, we will start to explain the Hill sorting

2. Hill sort

Hill sorting is based on direct insertion sorting, first grouping, then pre-sorting, adding grouping, sorting, and finally sorting success, let's take a look at the picture: direct insertion sorting of grouped elements, I started
insert image description here
with Three are a group of gaps with a distance of two for everyone to draw a picture to demonstrate. It is more intuitive.
insert image description here
This is Hill’s one-way sorting, but the actual code is going backward one by one. I know that the distance is a gap. Let everyone see more intuitively, let's take a look at the code for this sorting, and then look at the overall:

int gap = 2;
	for (int i = gap; i <=n - gap; i++)
	{
    
    
		int end = i;
		int key = a[end];
		while (end > 0)
		{
    
    
			if (key < a[end - gap])
			{
    
    
				a[end] = a[end - gap];
				end -= gap;
			}
			else
			{
    
    
				break;
			}
		}
		a[end] = key;
	}

We only made a small change for direct insertion sorting, changing the gap to 1 is direct insertion sorting.

The result of single-pass sorting:
insert image description here

For Hill sorting, I want to jump the largest number to the end as soon as possible, and the smallest number to the front as soon as possible, so I have the idea of ​​​​grouping, but in the end it is necessary to return to direct insertion sorting, that is, gap=1 , so how do we choose the gap at the beginning? Generally, half of the number of array elements is selected, because the array is closer to order later, and most of the desired data is in the corresponding range, so the range of the gap should be narrowed, divided by 2 at a time, and divided by any number by 2 , will be 1 in the end, let's take a look at the final sorting

We only need to ensure that the last gap=1 is enough, so we have another way of writing
gap=gap/3+1;
this is how we give the initial value of gap

void shellsort(int* a, int n)
{
    
    
	int gap=n;
	while (gap > 0)
	{
    
    
	   gap = gap/2;
	   gap=gap/3+1;
		for (int i = gap; i <= n - gap; i++)
		{
    
    
			int end = i;
			int key = a[end];
			while (end > 0)//因为都是和前面的数进行,加等于就跳到前面的位置,越界了,
			{
    
    
				if (key < a[end - gap])
				{
    
    
					a[end] = a[end - gap];
					end -= gap;
				}
				else
				{
    
    
					break;
				}
			}
			a[end] = key;
		}
		gap/=2;
	}
}

For Hill sorting, why is the efficiency better than direct insertion sorting? The reason is that when gap>1, they are all pre-sorted, and the purpose is to make the array closer to order. When gap == 1, the array is already close to order, so it will be very fast. In this way, the overall optimization effect can be achieved.

The time complexity of Hill sorting is not easy to calculate, because there are many ways to value the gap, which makes it difficult to calculate, so the time complexity of Hill sorting given in many trees is not fixed

Let's take a look at how other books introduce the time complexity of Hill sorting:
"Data Structure (C Language Edition)" - Yan Weimin

insert image description here
"Data Structure - Object-Oriented Method and C++ Description" - Yin Renkun It
insert image description here
's better for us to remember the conclusion, but it's okay if we can't. Yes, drawing pictures can be mastered very quickly.

3. Summary

The two sorts I’m talking about today belong to the insertion sort family. There are similarities and differences between the two. There is a performance gap between the two. I will update all the sorting articles before testing. Then today’s sorting is Let’s stop here first, everyone, come down and draw a picture to understand it yourself. In the next article, we will talk about the selection and sorting of the family
insert image description here

Guess you like

Origin blog.csdn.net/qq_69369227/article/details/130020854