Java programming: sorting algorithm-Hill sorting

Problems with simple insertion sort

Let's look at the possible problems of simple insertion sort.
Array arr = {2,3,4,5,6,1} At this time, the number 1 (minimum) that needs to be inserted, the process is:

  1. {2,3,4,5,6,6}
  2. {2,3,4,5,5,6}
  3. {2,3,4,4,5,6}
  4. {2,3,3,4,5,6}
  5. {2,2,3,4,5,6}
  6. {1,2,3,4,5,6}

Conclusion: When the number to be inserted is a small number, the number of backward shifts increases significantly, which has an impact on efficiency.

Introduction to Hill Sorting

Hill sorting is a sorting algorithm proposed by Donald Shell in 1959. Hill sort is also a kind of insertion sort , it is a more efficient version of simple insertion sort after improvement, also known as reduced incremental sort .

Basic idea of ​​Hill sorting method

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

Hill sorting diagram

Insert picture description here
Insert picture description here

Hill sorting application example:

There is a group of calves, the test scores are {8,9,1,7,2,3,5,4,6,0} Please sort from small to large. Please use them separately
Insert picture description here

  1. When Hill sorting, the exchange method is used when inserting the ordered sequence, and the sorting speed is tested.
  2. When Hill sorting, the moving method is used when inserting the ordered sequence, and the sorting speed is tested

Code

package sort;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class ShellSort {
    
    
    public static void main(String[] args) {
    
    
        /*int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
        shellSort(arr);
        System.out.println(Arrays.toString(arr));*/

        //希尔排序测速
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
    
    
            arr[i] = (int) (Math.random() * 80000);// 生成一个0-80000的数据
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间为:" + date1Str);
        shellSort(arr);
        Date date2 = new Date();
        String date2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间为:" + date2Str);
    }

    //根据前面的逐步分析,使用循环处理
    // 希尔排序交换法
    public static void shellSort1(int[] arr) {
    
    
        int temp = 0;
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    
            for (int i = gap; i < arr.length; i++) {
    
    
                for (int j = i - gap; j >= 0; j -= gap) {
    
    
                    if (arr[j] > arr[j + gap]) {
    
    
                        temp = arr[j];
                        arr[j] = arr[j + gap];
                        arr[j + gap] = temp;
                    }
                }
            }
        }
    }

    // 对交换式的希尔排序进行改进 →→→→ 移位法
    public static void shellSort(int[] arr) {
    
    
        // 仍然使用增量gap,并逐步缩小增量
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
    
    
            // 从第gap个元素开始,逐个对其所在的组进行直接插入
            for (int i = gap; i < arr.length; i++) {
    
    
                if (arr[i] < arr[i - gap]) {
    
    
                    int j = i;
                    int temp = arr[j];
                    while (j - gap >= 0 && temp < arr[j - gap]) {
    
    
                        // 移动
                        arr[j] = arr[j - gap];
                        j -= gap;
                    }
                    // 当退出while循环后,给temp找到插入位置
                    arr[j] = temp;
                }
            }
        }
    }

    // 使用逐步推导的方式编写希尔排序
    public static void shellSort2(int[] arr) {
    
    
        // 希尔排序第1轮排序
        // 思路:
        // 因为第1轮排序,将10个数据分成了5组
        int temp = 0;
        for (int i = 5; i < arr.length; i++) {
    
    
            // 遍历各组中所有的元素(共有5组,每组有2个元素),步长是5
            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));

        // 希尔排序第2轮排序
        for (int i = 2; i < arr.length; i++) {
    
    
            // 遍历各组中所有的元素(共有5组,每组有2个元素),步长是5
            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));

        // 希尔排序第3轮排序
        for (int i = 1; i < arr.length; i++) {
    
    
            // 遍历各组中所有的元素(共有5组,每组有2个元素),步长是5
            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));
    }
}

Guess you like

Origin blog.csdn.net/KaiSarH/article/details/108842071