希尔排序及其效率测试

希尔排序

在说希尔排序之前我们来看看插入排序存在的效率问题:
在这里插入图片描述
可以看出当插入排序要插入的数比较小的时候,我们需要对数组进行多次后移,这样就会对效率有很大影响。
插入排序对于小规模的数据或者是基本有序时很高效,数据有序程度越高,插入排序的效率越高,希尔排序正是利用了这一点。

  • 希尔排序介绍
    希尔排序是希尔与1959年提出的一种排序算法,希尔排序也是一种插入排序,它的简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序

  • 希尔排序思想

  1. 设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入排序。然后缩小间隔increment,重复上述子序列划分和排序工作。直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
  2. 由于开始时,increment的取值较大,每个子序列中的元素较少,排序速度较快,到排序后期increment取值逐渐变小,子序列中元素个数逐渐增多,但由于前面工作的基础,大多数元素已经基本有序,所以排序速度仍然很快
  • 希尔排序示意图
    在这里插入图片描述

  • 希尔排序代码实现

public class ShellSort {

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

    }

    public static void sort(int[] array) {
        // 需要进行次数,每次增量都除以二
        for (int increment = array.length/2; increment > 0; increment = increment/2) {
            // 遍历,进行排序
            for (int i = 0; i < array.length - increment; i++) {
                int insertVal = array[i + increment];
                int insertIndex = i;
                // 插入排序,每次都是通过increment递减
                for (int j = i ; j >= 0; j = j - increment) {
                    if (array[j] > insertVal) {
                        if (j - increment < 0) {
                            insertIndex = j;
                        }
                        array[j + increment] = array[j];
                    } else {
                        insertIndex = j + increment;
                        break;
                    }
                }

                if (insertIndex != i + increment) {
                    array[insertIndex] = insertVal;
                }

            }
        }

    }
}

排序结果

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

下面我们对希尔排序的效率进行测试

public static void main(String[] args) {
//        int[] array = {8,9,1,7,2,3,5,4,6,0};
        int[] array = new int[80000];
        for (int i = 0; i < array.length; i++) {
            // 随机生成一个0到8000000的随机数
            Random random = new Random();
            int nextInt = random.nextInt(8000000);
            array[i] = nextInt;
        }
        // 排序前时间,h毫秒
        long beforeSortTimeMillis = System.currentTimeMillis();
        sort(array);
        // 排序后时间
        long afterSortTimeMillis = System.currentTimeMillis();
        System.out.println("排序总共花费时间为:" + (afterSortTimeMillis - beforeSortTimeMillis) + "毫秒");

//        System.out.println(Arrays.toString(array));


运行结果:

排序总共花费时间为:20毫秒

从结果我们可以看到对8万个数据进行排序,希尔排序才用了20毫秒,而插入排序,选择排序(可以参考我的文章插入排序与选择排序)需要2000毫秒,说明希尔排序对大数量的排序比较友好,如果要排序的数据量比较大我们可以考虑希尔排序。

发布了83 篇原创文章 · 获赞 3 · 访问量 9852

猜你喜欢

转载自blog.csdn.net/fyj13925475957/article/details/103716524