希尔排序
插入排序的改进版本,改进的地方是引入了缩小增量的方式,因此希尔排序也称缩小增量排序。
思路:
- 先把数组按下标的一定增量进行分组
- 对划分的组别进行插入排序
- 缩小增量,继续步骤1,步骤2。直到增量递减至1时,算法停止。
如下图所示:
第一轮划分
第二轮划分
经过第一轮后,7的位置已经在9前面,5与6保持原样
第三轮划分
因为增量为1,第三轮不再划分小组,直接进行插入排序。
实现代码
func ShellSort(array []int) []int {
//h为增量
h := 1
for h < len(array)/2 {
h = h*2 + 1
}
for h >= 1 {
//此过程类似于插入排序的过程
for i := h; i < len(array); i++ {
value := array[i]
j := i
for ; j >= h; j -= h {
if array[j-h] > array[j] {
array[j] = array[j-h]
} else {
break
}
}
array[j] = value
}
h /= 2
}
return array
}
func main() {
array := []int{39, 2, 5, 23, 54, 12, 78, 34, 45, 40}
array = ShellSort(array)
for i, v := range array {
fmt.Printf("下标为%d的值为%d", i, v)
fmt.Println()
}
}
总结
- 空间复杂度:因为希尔排序是插入排序的改进版,它的空间复杂度与插入排序类似,O(1)。
- 稳定性:不稳定的,因为希尔排序会经过几轮的增量划分,每次划分而来的小组都进行插入排序,会导致最终结果中相同元素的相对位置会被打乱。
- 时间复杂度:希尔排序的时间复杂度为O(nlogn)。