Data structure and algorithm-two ways to implement Hill sorting

source

Before explaining Hill sorting, let us first understand the origin of Hill sorting. In fact, Hill sort is also an insertion sort. It is an advanced insertion sort that was invented by Great God Hill and optimized for simple insertion sort . That is to say, Hill sort is also an insertion sort. Let's understand the problems of simple sorting.

Problems with simple insertion sort

Let's look at the possible problems of simple insertion sort. The
array arr = {2,3,4,5,6,1} At this time, the number 1 (minimum) that needs to be inserted, such a process is:
{2,3,4, 5,6,6}
{2,3,4,5,5,6}
{2,3,4,4,5,6}
{2,3,3,4,5,6}
{2,2, 3,4,5,6}
{1,2,3,4,5,6}
Conclusion: When the number to be inserted is a smaller number, the number of back shifts increases significantly, which has an impact on efficiency.

The basic idea of ​​Hill sorting

How is Hill sorting optimized? That is, how to make the smaller number in the insert sorting move to a suitable position after a smaller number of backward shifts.

Please see professional explanation:

Hill sorting is to group records by a certain increment of subscript, and use the direct insertion sort algorithm to sort each group; as the increment gradually decreases, each group contains more and more keywords. When the increment decreases to 1, The entire file is just divided into a group and the algorithm terminates

If you can understand it, you are awesome. Anyway, I didn't understand it. Here are some algorithm pictures to help you understand this algorithm.

Insert picture description here

To put it simply, something called a gap is added to the Hill sort. Its initial size is equal to half the length of the array, and it is reduced by half every cycle. Its role is to group the array, group the array elements in twos, and perform insertion sorting, so that the sorting operation can be completed with as few moves as possible.

Implementation

Later, we come to specific code implementation:

Suppose we sort the array arr [8,9,1,7,2,3,5,4,6,0], Hill. According to the knowledge mentioned above.

  1. First determine whether the increment is greater than 0
    2) Calculate increment = arr.length / 2 = 5
    3) Group 8-> 3, 9-> 5, 1->
    4, 7-> 6, 2-> 0 3) and Determine if you need to swap positions in the
    first round
//根据length/2 = 5 ,步长 = 5
		for(int i = 5; i<arr.length; i++) {
			//如果当前元素大于加上步长后的那个元素,说明交换
			for(int j=i-5;j>=0;j-=5) {
				if(arr[j] > arr[j+5]) {
					temp = arr[j];
					arr[j]=arr[j+5];
					arr[j+5]=temp;
				}
			}
		}
		System.out.println("希尔排序1轮后:"+Arrays.toString(arr));

second round

//步长 = 5/2 =2
		for(int i = 2; i<arr.length; i++) {
			for(int j=i-2;j>=0;j-=2) {
				if(arr[j] > arr[j+2]) {
					temp = arr[j];
					arr[j]=arr[j+2];
					arr[j+2]=temp;
				}
			}
		}
		
		System.out.println("希尔排序2轮后:"+Arrays.toString(arr));

Third round

//步长 = 2/2 = 1
		for(int i = 1; i<arr.length; i++) {
			for(int j=i-1;j>=0;j-=1) {
				if(arr[j] > arr[j+1]) {
					temp = arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
		}
		
		System.out.println("希尔排序3轮后:"+Arrays.toString(arr));
		*/

Running results
Insert picture description here
Here is my Java code in elipse, too lazy to type python again.

Here is the exchange-based Hill sorting code after Python integration:

def shellSort(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            for j in range(i-gap,-1,-gap):
                if arr[j]>arr[j+gap]:
                    temp = arr[j]
                    arr[j] = arr[j+gap]
                    arr[j+gap] = temp


However, because the value of two elements is exchanged, similar to the bubble sort, the time efficiency is very low. Therefore, it is necessary to improve the operation of moving elements to a suitable position and inserting elements after inserting sorting.

def shellSort2(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            j = i
            temp = arr[j]
            if arr[j]<arr[j-gap]:
                #先移位
                while(j-gap>=0 and temp<arr[j-gap]):
                    arr[j] = arr[j-gap]
                    j -= gap
                #后插入
                arr[j] = temp

This is a Hill sorting code that uses mobile exchange locations. Now let's test whether it improves time efficiency. Import the time and random modules to create a random array with 8000 elements. The specific code is as follows:

import time
import random

#arr = [8,9,1,7,2,3,5,4,6,0]

arr = [0 for i in range(8000)]
for i in range(8000):
    arr[i]=random.randint(0,8000)

def shellSort(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            for j in range(i-gap,-1,-gap):
                if arr[j]>arr[j+gap]:
                    temp = arr[j]
                    arr[j] = arr[j+gap]
                    arr[j+gap] = temp


def shellSort2(arr):
    temp = 0
    gap = len(arr)
    while gap>1:
        gap = int(gap/2)
        for i in range(gap,len(arr),1):
            j = i
            temp = arr[j]
            if arr[j]<arr[j-gap]:
                #先移位
                while(j-gap>=0 and temp<arr[j-gap]):
                    arr[j] = arr[j-gap]
                    j -= gap
                #后插入
                arr[j] = temp
print("交换式希尔排序:")
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
shellSort(arr)
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
#print(arr)

print("插入式希尔排序:")
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
shellSort2(arr)
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
#print(arr)

The operation results are shown in the figure: it
Insert picture description here
can be seen that the time efficiency has been greatly improved, from the original 9 seconds to less than 1 second. Ok, sharing is finished.

Published 27 original articles · praised 2 · visits 680

Guess you like

Origin blog.csdn.net/qq_44273739/article/details/105243321