排序算法——希尔排序

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)
posted @ 2019-05-28 16:16  笃志弘毅  阅读(212)  评论(0编辑  收藏  举报