概述
思路 先将整个待排序的记录序列分割成为若干子序列,
分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
希尔排序亦称之为增量递减排序,是对插入排序的改进,因此有必要先了解下插入排序。
插入排序
工作原理 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法主要在于移动有序序列位置,寻找被插入数据在有序数据中的位置点,其golang
与 python
算法如下
func insertSort(arr []int) []int {
for i:=range arr {
// 临时存入当前数值
current := arr[i]
// 合理假定指针i左侧皆为有序子列
j := i - 1
// 跳出时为可插入点的前一个数索引
for j >= 0 && arr[j] > current {
// 前数向后挪位
arr[j+1] = arr[j]
// 有序组指针前移,从后往前扫描
j -= 1
}
// 将当前值插入到合适的有序位,+1补偿内层计算偏移
arr[j+1] = current
}
return arr
}
python 实现
def insertionSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
希尔排序
建立在插入排序之上,需要解决的是增量退出,给插入排序加个壳即可如下所示
php 实现
function insertSort($arr)
{
$len = count($arr);
$temp = 0;
$gap = 1;
// $gap 组元素间索引差
while($gap < $len / 3) {
// +1确保最后会被全员进行一次插入重排调整, 3为分组尺度
$gap = $gap * 3 + 1;
}
for ($gap; $gap > 0; $gap = floor($gap / 3)) {
for ($i = $gap; $i < $len; $i++) {
$temp = $arr[$i];
for ($j = $i - $gap; $j >= 0 && $arr[$j] > $temp; $j -= $gap) {
$arr[$j+$gap] = $arr[$j];
}
$arr[$j+$gap] = $temp;
}
}
return $arr;
}