1、算法介绍
希尔排序(缩小增量排序),是直接插入排序的一种改进版本,是非稳定排序算法。
(1)待排序序列长度n;
(2)选取增量d,一般d小于等于n/2,按增量d分割若干个子序列分别进行直接插入排序;
(3)缩小增量d,再分割成若干子序列分别进行直接插入排序;
(4)重复步骤3直至增量为0,整个序列最后进行一次直接插入排序;
由上可知希尔排序是根据以下两点改进直接插入排序算法的:
》直接插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
》但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
直接插入排序等价于增量为1的希尔排序。
2、代码实现
2.1、golang
package main import ( "fmt" ) func main() { slice := []int{5, 3, 12, 54, 23, 12, 6, 9, 19} //SortInsert(slice) //SortInsertByInc(slice, 1) SortShell(slice) fmt.Println(slice) } //直接插入排序 func SortInsert(slice []int) { n := len(slice) for i := 1; i < n; i++ { for j := i; j >= 1 && slice[j-1] > slice[j]; j-- { slice[j], slice[j-1] = slice[j-1], slice[j] } } } //直接插入排序》带增量的直接插入排序 //直接插入排序等价于增量为1的希尔排序 func SortInsertByInc(slice []int, inc int) { n := len(slice) for i := inc; i < n; i++ { //增量插入排序 for j := i; j >= inc && slice[j-inc] > slice[j]; j -= inc { slice[j], slice[j-inc] = slice[j-inc], slice[j] } } } //希尔排序 func SortShell(slice []int) { for inc := len(slice) / 2; inc > 0; inc /= 2 { //循环缩小增量 SortInsertByInc(slice, inc) } }
2.2、python3
# 直接插入排序 def sort_insert(arr): n = len(arr) for i in range(1, n): for j in range(i, 0, -1): if arr[j - 1] > arr[j]: arr[j], arr[j - 1] = arr[j - 1], arr[j] else: break # 按增量直接插入排序 def sort_insert_by_inc(arr, inc): n = len(arr) for i in range(inc, n): for j in range(i, inc - 1, -1): if arr[j] < arr[j - inc]: arr[j], arr[j - inc] = arr[j - inc], arr[j] else: break # 希尔排序 def sort_shell(arr): inc = len(arr) // 2 # 选择增量 while inc > 0: sort_insert_by_inc(arr, inc) inc //= 2 # 缩小增量 if __name__ == '__main__': arr = [5, 3, 12, 54, 23, 12, 6, 9, 19] # sort_insert(arr) # sort_insert_by_inc(arr, 1) sort_shell(arr) print(arr)