Reject hydrology! Eight Sorts (1) [Suitable for Beginners] Direct Insertion Sort and Hill Sort

Article directory


Hello everyone, my name is Ji Ning.
This article will introduce you to the direct insertion sort algorithm and the Hill sort algorithm.

direct insertion sort

直接插入排序It is a simple insertion sort method. Its basic idea is to insert the records to be sorted into an already sorted sequence one by one according to the size of their key values. Until all records are inserted, a new ordered sequence.
Just like when you play poker, every time you receive a card, you will habitually insert it into the appropriate position. Finally, you will get a neat deck of cards. This is the principle of insertion sort.
Insert image description here

插入排序动态图解

Insert image description here
If you want to sort in ascending order now, you need to 'insert' it into the original sequence starting from the second data.

具体步骤(以升序为例子)
Starting from the second data, save the data A first, and then compare the data A with the previous data in sequence. If the data A is smaller than the previous number (indicating that the position of A should be in front of this number), then the previous number will be Move back one position until data A is greater than or equal to a certain previous number, then place data A after this number (the number at the back of this number has been moved back to its next position)

代码实现

void InsertSort(int* a, int n)//直接插入排序
{
    
    
	for (int i = 1; i < n; i++)
	{
    
    
		int end = i;//从第二个位置开始
		int tmp = a[end];//先保存这个值
		while (end > 0)
		{
    
    
			if (tmp < a[end - 1])
			{
    
    
				a[end] = a[end - 1];
				end--;
			}
			else
			{
    
    
				break;//如果不符合,就直接退出了
			}
		}
		a[end] = tmp;
	}
}

Easy to make mistakes: Use tmp to compare with each previous value in sequence (a[end] cannot be used), because the value of end is always changing. Each insertion can only insert one number into the original sequence, and the inserted number is this tmp.

复杂度分析

In the worst case, each trip must be compared with 'full', so starting from the second one, 1 2 3 4 ... n must be compared in sequence, and the cumulative result is: the magnitude is N^2. But in the best case (ordered), this person's sorting only needs to be traversed once to complete the sorting, and the magnitude is N.So when the sequence is close to ordered, the efficiency of direct insertion sort can be close to O(N)
Insertion sort does not open additional space. And it is arranged in order from back to front, and stops when it encounters an equal, so this sorting is very stable.
Time complexity: O(N^2)
Space complexity: O(1)
Stability:不稳定

Hill sort

Insertion sort is a very good sort. Especially when the sequence is close to ordered, the efficiency can even reach close to O(N). So how can we design an algorithm to pre-sort the data first so that the sequence can be inserted as a whole? Can we achieve a nearly ordered state before sorting?

希尔排序
Hill sorting method is also called shrinking increment method. The basic idea of ​​Hill sorting method is: first select an integer, divide all the records in the file to be sorted into groups, put all the records with distance into the same group, and sort the records in each group. Then, take and repeat the above grouping and sorting work. When =1 is reached, all records are sorted in the same group.

The specific steps are to divide this data into multiple groups, with gaps of data between the members of each group, and perform insertion sorting for each group, so that small numbers can be in the front as much as possible and large numbers can be in the back; and then the gaps can be reduced in scale. , repeat the above steps, and finally when the gap is equal to 1, it is direct insertion sorting, and the sequence at this time is already very close to an ordered state.
Insert image description here

代码实现

The first is grouping, sorting each group separately.

void ShellSort(int* a, int n)//希尔排序
{
    
    
	int gap = n / 3;
	while (gap >= 1)
	{
    
    
		for (int z = 0; z < gap; z++)//gap组数据
		{
    
    
			for (int i = z; i < n - gap; i += gap)//对一组进行直接插入排序
			{
    
    
				int end = i;
				int tmp = a[end + gap];
				for (int j = end; j < n-gap; j += gap)
				{
    
    
					while (end>=0)
					{
    
    
						if (tmp < a[end])
						{
    
    
							a[end + gap] = a[end];
						}
						else
						{
    
    
							break;
						}
						end -= gap;
					}
					a[end + gap] = tmp;
				}

			}
		}
		gap /= 2;//调整gap的值
	}
}

Features: The idea is relatively simple, but there are many loops and the code is complex.

The second type is grouping, but the overall order is from the beginning to the bottom, and gap data is skipped each time during insertion sort.

void ShellSort(int* a, int n)//希尔排序
{
    
    
	int gap = n / 3;
	while (gap >= 1)
	{
    
    
		for (int i = 0; i < n - gap; i++)
		{
    
    
			int end = i;
			int tmp = a[end + gap];
			for (int j = end; j < n-gap; j += gap)
			{
    
    
				while (end>=0)
				{
    
    
					if (tmp < a[end])
					{
    
    
						a[end + gap] = a[end];
					}
					else
					{
    
    
						break;
					}
					end -= gap;
				}
				a[end + gap] = tmp;
			}

		}
		gap /= 2;  
	}
}

It is difficult for beginners to think, but after understanding, the code will be simpler and easier to control, and less prone to errors.

复杂度分析
time complexity:O(N^1.3) Close to O(N*logN)
Space Complexity: O(1)
Stability:不稳定

Guess you like

Origin blog.csdn.net/zyb___/article/details/133481857