在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; } }