希尔排序法

Posted 算法精解

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了希尔排序法相关的知识,希望对你有一定的参考价值。

简介

希尔(Shell)排序又称为缩小增量排序,该排序方法也属于插入排序类的算法,是对插入排序的一种改进。

算法描述

希尔排序的基本思想就是:将需要排序的序列化分为若干个较小的序列,对这些序列进行直接插入排序,通过这样的操作可使需要排序的数列基本有序,最后再使用一次直接插入排序对整个数列进行排序9。这样,首先对数量较小的序列进行直接插入排序可提高效率,最后对基本有序的序列进行直接插入排序,也可以提高效率,从而使整个排序过程的效率得到提升。
下面以一组待排序的数据演示希尔排序的过程,假设有8个需要排序的数据序列如下:
69, 65, 90, 37, 92, 6, 28, 54
使用希尔排序法进行排序的过程如图1所示,具体排序过程如下:

图1 希尔排序过程

(1)首先使用元素总数量的一半(值为4)作为增量,将数据划分为4个子序列。对这4个序列分别进行排序,其中第2、6和第3、7子序列需要进行数据交换。交换后得到第1遍排序的结果。
(2)接着将增加缩小一半(值为2)重新划分子序列,得到两个子序列。对这两个子序列分别进行排序,得到第2遍排序后的结果。
(3)再次缩小增量(值为1),此时所有数据构成1个序列,对该序列使用直接插入排序,得到最后排序结果。
在图1所示的排序过程中,第1遍排序进行了两次数据交换(65与6交换、90与28交换),第2次排序进行了3次数据交换(69与28交换、90与92交换、65与54交换),最后一遍进行了7次数据交换(不再列出,读者可去分析),一共需交换数据12次。
如果不使用希尔排序,而使用直接插入排序对原数据进行排序,则需要进行19次数据交换,算法的效率大大降低。
由此可见,使用希尔排序法可显著地减少数据交换的次数,从而提高排序的效率。
算法实现
希尔排序Golang代码如下。
func ShellSort(arr[] int) { // 计算第1次的增量 d := len(arr) / 2 // 循环至增量为1时结束 for d >= 1 { for i := d; i < len(arr); i++ { // 获取序列中的下一个数据 next := arr[i] // 序列中前一个数据的序号 j := i - d // 下一个数大于钱一个属 for j >= 0 && arr[j] > next { arr[j + d] = arr[j] j = j - d } // 保存数据 arr[j + d] = next } // 缩小增量 d /= 2 }}
测试用例:
func TestShellSort(t *testing.T) { rand.Seed(time.Now().Unix()) var arr []int for i := 0; i < 10; i++ { temp := rand.Intn(1000) arr = append(arr, temp) } originSort, origin := append([]int{}, arr...), append([]int{}, arr...) sort.Ints(originSort) shellSort.ShellSort(arr) if !reflect.DeepEqual(originSort, arr) { t.Errorf("Got %v for input %v; expected %v", arr, origin, originSort) }}
测试结果如图2所示。

图2 测试结果

相关文章:

《零基础学算法第2版》4.6直接插入排序法


以上是关于希尔排序法的主要内容,如果未能解决你的问题,请参考以下文章

基础排序算法总结(代码+图片分析)

希尔排序法(缩小增量法)

希尔排序(交换法&移位法)

希尔排序法

希尔排序法

插入排序与希尔排序