Disassembly and analysis of Hill sorting algorithm

Foreword : After reading a lot of explanations on the Internet, it feels not very intuitive. So I plan to use a vernacular to explain the Hill algorithm clearly. Everyone knows that it is actually an improved version of insertion sort. We all know that if there are more locally ordered numbers in a set of data, the more efficient insertion sort is. (If you don’t understand, you can go to understand). Knowing this feature, the Hill algorithm was born from this.

First, let us review the insertion sort

//比如有组数据:
int[] arr = {
    
    8, 6, 2, 3, 1, 5, 7, 4};

Text summary: Assume that the first element is the smallest number. Then we have to loop backward from index=1, take the following numbers in turn, and compare them with the previous numbers to find the smallest number. That is, when index =1, then arr[1] is compared with arr[0]. When index = 2, compare arr[2] with arr[1] to get a minimum value, and then compare with arr[0]. Finally complete the sorting from small to large.

So the code is as follows

	//{8, 6, 2, 3, 1, 5, 7, 4}
    public void inseartSort(int[] arr) {
    
    
		//所以外层循环,我们跳过第一个元素 8,拿后面的数和前面的数比较
        for (int i = 1; i < arr.length; i++) {
    
    
			//1、这层的循环是拿后面的数和前面的【依次比较】得出最小数
            //2、下面内层循环不知道怎么写,我们可以先来拆分下逻辑
            //   (1)先看外层循环,index = 1,我们要拿arr[1]与arr[0]比较,较小的数字排在前面
            //   (2)继续看外层循环,index = 2,我们首先要拿arr[2]和arr[1]作比较,得出最小数后,继续和arr[0]做比较。
            // 	      相当于index--了。
			//	 (3)综上所述:外层循环的起始点,就是内层循环的起始点,其次index--才能依次和前面的数比较,做好排序。
            //        既然是index--,那么index要满足的条件是index > 0 。不然异常。所以代码如下
            for (int j = i; j > 0; j--) {
    
    
                if (arr[j] < arr[j - 1]) {
    
    
                    int temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }


Second, Hill sort

Know the insertion sort algorithm. A very long set of data. The more locally ordered numbers, the more efficient the insertion sort and the better the performance.
Hill algorithm: It is improved by using the characteristics of this insertion sort. He has a concept of incremental gap here. We will not discuss the time complexity brought by incremental sequence for the time being.

If it is still that set of data: {8, 6, 2, 3, 1, 5, 7, 4}. Assume that the increment here is gap = arr.length/2. That is 4, he will group the array logically into several parts (it can also be regarded as the increment is several parts), and then insert and sort the logical groups in turn, and the array is still the same array. Use gap /= 2 after sorting. That is 2. Continue to logically group, continue to insert sort. In this way, most of the data in the original array is ordered data. Finally, gap = 1, insert sorting the array where most of the data is ordered data. Then the speed is much faster, the performance is convenient and very efficient.

It may be very general, please see the analysis


2.1, when gap=4

When gap = 4, then

  • arr[0] and arr[4] set
  • arr[1] and arr[5] set
  • arr[2] and arr[6] set
  • arr[3] and arr[7] a set
//数据就对应如下
8  6  2  3  1  5  7  4
|  |  |  |  |  |  |  |
8--|--|--|--1  |  |  |  
   6--|--|-----5  |	 |
	  2--|--------7  |
		 3-----------4

This is a logical grouping,

  • After 8 and 1 are sorted: 1 8;
  • After 5 and 6 are sorted: 5 6;
  • After 2 and 7 are sorted: 2 7;
  • After 3 and 4 are sorted: 3 4.
8  6  2  3  1  5  7  4
|  |  |  |  |  |  |  |
1--|--|--|--8  |  |  |  
   5--|--|-----6  |	 |
	  2--|--------7  |
		 3-----------4

Looking vertically, the sorting results are: 1 5 2 3 8 6 7 4


2.2, when gap = 2

When the gap is 2, it will be separated by 2 to group, of course, it is divided into 2 groups

1  5  2  3  8  6  7  4
|  |  |  |  |  |  |  |
1--|--2--|--8--|--7  |  
   |     |     |     |
   |     |     |     |
   5-----3-----6-----4

The grouping when gap=2 is

  • 1 2 8 7; after sorting, 1 2 7 8
  • 5 3 6 4; after sorting, 3 4 5 6

Then it is

1  5  2  3  8  6  7  4
|  |  |  |  |  |  |  |
1--|--2--|--7--|--8  |  
   |     |     |     |
   |     |     |     |
   3-----4-----5-----6

Looking vertically, the sorting results are: 1 3 2 4 7 5 8 6

Finally, when gap = 1, it is normal insertion sort. Some people may say that if you do it in increments, the last set of data is not in order for most of the numbers. Because for the purpose of explanation, I chose relatively small data size=8. If size>=100000, it will be very obvious.


Three, the java expression of Hill sorting

Through the above explanation, we know. In fact, Hill sorting has an additional concept of increment, which is largely unchanged

First of all, we know the change of incremental gap

//不难理解,gap最终变化是4,2,1
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    }

Next, when we put gap=1, that is, the code for normal insertion sorting is directly moved in


   for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    
        for (int i = 1; i < arr.length; i++) {
    
    
            for (int j = i; j > 0; j--) {
    
    
                if (arr[j] < arr[j - 1]) {
    
    
                    int temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    
    
    
   //上面式子看不大出来,我们把它变一下如下
   //看看哪里时候把gap加上
   for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    
        for (int i = 1; i < arr.length; i++) {
    
    
            for (int j = i; j >= 1; j-=1) {
    
     //主要是修改了j>0 改成了 j>=1。 j-- 改成了 j-=1
                if (arr[j] < arr[j - 1]) {
    
    
                    int temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }




//改完之后,我们把gap=1的情况改成gap。也就是把1改成gap变化如下
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    
            for (int i = gap; i < arr.length; i++) {
    
    
                for (int j = i; j >= gap; j -= gap) {
    
    
                    if (arr[j] < arr[j - gap]) {
    
    
                        int temp = arr[j - gap];
                        arr[j - gap] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
        }


Well, that's it for Hill sorting! Next, we print it to verify the initial logic:

Guess you like

Origin blog.csdn.net/leol_2/article/details/107982564