插入排序 希尔排序

在Java,尽管有类库Arrays.sort(arr)可以让我们对数组进行排序,当我们参加笔试时,要对一些经典排序算法进行书写,这就要求我们能够写出一些基本的排序算法;本文想讲下希尔排序,但在希尔排序前,我们先谈谈插入排序。

插入排序

上图勾勒出了直接插入排序的步骤,以下我们直接出代码。

   /**
     * 插入排序
     * 
     * @param arr
     */
    public static void insertSort(long[] arr) {
        long temp = 0;
        int in = 0;
        for (int i = 1; i < arr.length; i++) {
            temp = arr[i];
            in = i;
            while (in > 0 && arr[in - 1] >= temp) {
                arr[in] = arr[in - 1];
                in--;
            }
            arr[in] = temp;
        }
    }

从该代码,我们可以看出,插入排序慢的不行。于是又另一种比较快的排序算法应运而生。

这就是shell。

希尔排序:

   直接插入排序的改进版,直接插入排序每次只能移动一位,而希尔排序根据特定的步长,移动距离大大增加。
希尔排序就是减少增量的排序方法,给出初始设定一个增量,然后根据这个增量将整个序列进行划分,划分成若干个子序列,然后对每  个子序列进行直接插入排序。 然后再将增量减少,然后再将整个序列划分成若干个子序列,然后在对每个子序列进行直接插入排序,依次类推,直到增量为1时,即   对整个序列进行直接插入排序,因为现在的序列已经基本有序,则直接插入排序的效率较高,这样完成后,我们的整个序列就完全有序。
进行排序时数据项之间的间隔称为
增量
/**
     * 希尔排序
     * 
     * @param arr
     */
    public static void shellSort(long[] arr) {
        // 初始化间隔
        int h = 1;
        // 计算最大间隔
        while (h < arr.length / 3) {
            h = 3 * h + 1;
        }

        while (h > 0) {
            // 进行插入排序
            long temp = 0;
            int in = 0;
            for (int i = 1; i < arr.length; i++) {
                temp = arr[i];
                in = i;
                while (in > h - 1 && arr[in - h] >= temp) {
                    arr[in] = arr[in - h];
                    in -= h;
                }
                arr[in] = temp;
            }
            // 减小间隔
            h = (h - 1) / 3;
        }

    }
原文地址:https://www.cnblogs.com/sunTin/p/6753737.html