原理
希尔排序是在插入排序的基础上做了一些优化。对于存在大规模乱序的数组,插入排序的性能会比较慢,因为它会交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。对于一些极端情况可能一个元素的移动次数就要是N-1
,希尔排序就是为了加快元素的移动而做的优化
希尔排序的思想就是使数组中任意间隔h
的元素都是有序的,这样的数组称为h有序数组
,在进行h有序化
时,如果h
的值比较大,那么元素一次性移动的距离就比较大,这样就可以减少元素移动的次数。h有序数组
并不代表数组就是有序的,只能说明是局部有序,还需要缩短h
的长度,直到h = 1
,希尔排序对大规模乱序的数组比较有效,对于乱序不是很严重的数组,效果可能还没有插入排序好,要知道每种算法都有其应用场景
实现
// Comparable 定义接口
type Comparable interface {
CompareTo(interface{}) int
}
// Int 定义类型并实现接口
type Int int
func (i Int) CompareTo(i2 Int) int {
i2tmp := int(i2)
iTmp := int(i)
if iTmp > i2tmp {
return 1
} else if iTmp < i2tmp {
return -1
} else {
return 0
}
}
// HillSort 希尔排序
// s : 输入
// flag : true-从小到大,false-从大到小
// return:输出
func HillSort(s []Int, flag bool) []Int {
l := len(s)
h := 1
n := 3
// 1,4,7,10,13,16...
for (n*h + 1) < l {
h = n*h + 1
}
for h >= 1 {
for i := h; i < l; i++ {
for j := i; j >= h; j -= h {
if flag && s[j].CompareTo(s[j-h]) < 0 || !flag && s[j].CompareTo(s[j-h]) > 0 {
s[j], s[j-h] = s[j-h], s[j]
} else {
// 元素移动到指定位置后,不再继续遍历
break
}
}
}
h = (h - 1) / n
}
return s
}
注:部分内容引自书籍,如果存在抄袭,请留言,一定尽快调整