目录
Shellsort是最古老的排序算法之一,该算法以其发明者Donald L. Shell的名字命名(1959)。在ShellSort排序算法之前的算法时间复杂度基本都是 O(n2) ,该算法是突破这个时间复杂度的第一批算法之一。另外 Shellsort 是快速、易于理解和易于实现的。 然而,其复杂度分析有点复杂。
1.Shellsort的思想
学过InsertSort排序的都应该了解,直接插入排序算法适用于 基本有序和数据量不大的排序序列。基于这两点1959年Donald L. Shell提出了希尔排序,又称“缩小增量排序”。
基本有序:就是小的关键字基本都在前面,大的关键字基本都在后面,不大不小的关键字基本都在中间。例如:{ 213647589 }就可以称为基本有序,但{ 159378246 }就谈不上基本有序。—–《大话数据结构》
Shellsort的思路如下:
a. 将待排序的数据序列排列在二维数组中
b. 对数组的列进行排序
经过上面两步处理后数据序列被部分排序。 重复上述过程,但每次使用较窄的二维数组,即数组具有较少数量的列。 在最后一步中,数组只包含一列。 在每个步骤中,序列的排序增加,直到在最后一步中它被完全排序。 然而,由于在前面的步骤中获得的序列的预排序,每个步骤中必需的排序操作的数量是有限的。
示例: 设 37905168420615734982 是要排序的数据序列。 首先,它被排列在具有7列(左)的数组中,然后列被排序(右):
将待排序的数据序列排列在二维数组中 | 对数组的列进行排序后 | |
---|---|---|
38774392400956811265
| → |
37834724900956811256
|
经过一次ShellSort后,序列变成
33205157440616879982
。数据元素
8
和
将待排序的数据序列排列在二维数组中 | 对数组的列进行排序后 | |
---|---|---|
01345780235679124689
目前序列变为
00112233445656877989
。序列几乎完全排序。 在最后一步中将该序列布置在一列中时,只需将
6
, 2.代码实现 实际上在用代码实现Shellsort算法时,数据序列不是布置在真实的二维数组中,而是布置在用适当索引控制的一维数组中。 例如,可以将数组索引为 以下程序数组
a[0,n−1)
进行排序。 用于在每个步骤中排列数据的列数(增量序列)已保存在数组cols中。 因此,第一次数据排列时,数据序列被布置为1391376列;第二次被布置为463792列;在最后一步中被布置在
1
列中。 (注意,如果列的数量
3.增量序列
|