Sort Hill
En 1959, un Donald L. Shell (March 1, 1924 – November 2, 2015)
estadounidense llamado Communications of the ACM 国际计算机学会月刊
lanzó un algoritmo de clasificación, y nació el algoritmo llamado clasificación de Hill.
Nota: La ACM = Association for Computing Machinery
International Computer Society, una organización profesional mundial para profesionales de la informática, fundada en 1947, es la primera sociedad informática y educativa del mundo.
La ordenación en pendiente es una versión mejorada de la ordenación por inserción directa. Debido a que la ordenación por inserción directa es muy eficiente para aquellas secuencias que casi ya están ordenadas, logra O(n)
una complejidad lineal, pero solo puede mover los datos un bit a la vez. En la clasificación creativa de Hill, los datos se pueden cambiar un n
poco y luego n
siempre se reducirán a la misma clasificación de inserción directa 1
. Consulte el siguiente análisis.
La clasificación de colinas es un algoritmo de clasificación de inserción.
1. Introducción al algoritmo
Hay una N
secuencia de números:
- Primero tome un
N
número entero menor qued1
,d1
agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique estos números directamente. - Luego tome un
d1
número entero menor qued2
,d2
agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique los números directamente. - Luego tome un
d2
número entero menor qued3
,d3
agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique los números directamente. - ...
- Hasta que obtenga el número entero
d=1
, utilice el tipo de inserción directa.
Este es un método de inserción de agrupación. La última iteración es equivalente a la ordenación por inserción directa. Las otras iteraciones son equivalentes a n
la ordenación por inserción directa moviendo una distancia cada vez . Estos enteros son la distancia entre dos números.
Tomamos la mitad de la longitud de la secuencia como un incremento y luego la reducimos a la mitad cada vez hasta que el incremento sea 1.
Como un ejemplo simple, Hill ordena una secuencia de 12 elementos :, [5 9 1 6 8 14 6 49 25 4 6 3]
y los d
valores de incremento están en orden 6,3,1
::
x 表示不需要排序的数
取 d = 6 对 [5 x x x x x 6 x x x x x] 进行直接插入排序,没有变化。
取 d = 3 对 [5 x x 6 x x 6 x x 4 x x] 进行直接插入排序,排完序后:[4 x x 5 x x 6 x x 6 x x]。
取 d = 1 对 [4 9 1 5 8 14 6 49 25 6 6 3] 进行直接插入排序,因为 d=1 完全就是直接插入排序了。
Cuanto más ordenada sea la secuencia, mayor 1
será la eficiencia de la ordenación por inserción directa. La ordenación en pendiente utiliza la ordenación por inserción directa por agrupación. Debido a que el tamaño del paso es mayor, la secuencia desordenada se puede cambiar rápidamente a menos desordenada al principio El número de intercambios también se reduce, hasta que 1
se utiliza el último paso de la clasificación de inserción directa, la secuencia ya está relativamente ordenada, por lo que la complejidad del tiempo será ligeramente mejor.
En el mejor de los casos, es decir, cuando se ordena la secuencia, la clasificación de Hill debe realizar logn
una clasificación de inserción directa sub-incremental, porque la complejidad de tiempo óptima de cada clasificación de inserción directa es :, O(n)
entonces, el mejor momento para la clasificación de Hill O(nlogn)
complejidad: .
En el peor de los casos, cada iteración es la peor, suponiendo que la secuencia incremental es :, d8 d7 d6 ... d3 d2 1
entonces el número de elementos de clasificación insertados directamente es :, n/d8 n/d7 n/d6 .... n/d3 n/d2 n
entonces la complejidad temporal se calcula como la peor complejidad de la inserción directa :
假设增量序列为 ⌊N/2⌋ ,每次增量取值为比上一次的一半小的最大整数。
O( (n/d8)^2 + (n/d7)^2 + (n/d6)^2 + ... + (n/d2)^2 + n^2)
= O(1/d8^2 + 1/d7^2 + 1/d6^2 + ... + 1/d2^2 + 1) * O(n^2)
= O(等比为1/2的数列和) * O(n^2)
= O(等比求和公式) * O(n^2)
= O( (1-(1/2)^n)/(1-1/2) ) * O(n^2)
= O( (1-(1/2)^n)*2 ) * O(n^2)
= O( 2-2*(1/2)^n ) * O(n^2)
= O( < 2 ) * O(n^2)
Por lo tanto, el peor momento de complejidad de la clasificación de Hill es O(n^2)
.
Las diferentes secuencias de incremento de agrupación tienen una complejidad de tiempo diferente, pero nadie puede probar qué secuencia es la mejor. Hibbard
Incremental de secuencia: 1,3,7,···,2n−1
una secuencia de paquetes puede ser probado ampliamente, complejidad del tiempo es: Θ(n^1.5)
.
La complejidad temporal de la clasificación de Hill se trata de este rango: O(n^1.3)~O(n^2)
es imposible demostrarlo estrictamente por las matemáticas.
La ordenación en pendiente no es estable, porque cada ronda de agrupación utiliza la ordenación por inserción directa, pero la agrupación abarcará n
posiciones, lo que dará como resultado dos números idénticos, y el cambio de orden no se puede encontrar si no se puede encontrar a la otra parte.
2. Implementación de algoritmos
package main
import "fmt"
// 增量序列折半的希尔排序
func ShellSort(list []int) {
// 数组长度
n := len(list)
// 每次减半,直到步长为 1
for step := n / 2; step >= 1; step /= 2 {
// 开始插入排序,每一轮的步长为 step
for i := step; i < n; i += step {
for j := i - step; j >= 0; j -= step {
// 满足插入那么交换元素
if list[j+step] < list[j] {
list[j], list[j+step] = list[j+step], list[j]
continue
}
break
}
}
}
}
func main() {
list := []int{5}
ShellSort(list)
fmt.Println(list)
list1 := []int{5, 9}
ShellSort(list1)
fmt.Println(list1)
list2 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
ShellSort(list2)
fmt.Println(list2)
list3 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3, 2, 4, 23, 467, 85, 23, 567, 335, 677, 33, 56, 2, 5, 33, 6, 8, 3}
ShellSort(list3)
fmt.Println(list3)
}
Salida:
[5]
[5 9]
[1 3 4 5 6 6 6 8 9 14 25 49]
[1 2 2 3 3 4 4 5 5 6 6 6 6 8 8 9 14 23 23 25 33 33 49 56 85 335 467 567 677]
De acuerdo con varios algoritmos de ordenación analizados anteriormente, generalmente se recomienda usar la ordenación por inserción directa cuando la matriz que se va a ordenar es de pequeña escala. La ordenación en pendiente se puede usar en casos de tamaño mediano, pero aún se requiere una ordenación rápida, una fusión o una gran cantidad. Ordenar
Entrada de artículo de serie
Soy la estrella Chen, bienvenido he escrito personalmente estructuras de datos y algoritmos (Golang lograr) , comenzando en el artículo para leer más amigable GitBook .
- Estructura de datos y algoritmo (implementación de Golang) (1) Una introducción simple a Golang-Prefacio
- Estructuras de datos y algoritmos (implementación de Golang) (2) Una introducción simple a los paquetes, variables y funciones de Golang
- Estructura de datos y algoritmo (implementación de Golang) (3) Una introducción simple a la declaración de control de flujo de Golang
- Estructuras de datos y algoritmos (implementación de Golang) (4) Una introducción simple a las estructuras y métodos de Golang
- Estructura de datos y algoritmo (implementación de Golang) (5) Una introducción simple a la interfaz de Golang
- Estructura de datos y algoritmo (implementación de Golang) (6) Una introducción simple a la concurrencia, las rutinas y los canales de Golang
- Estructura de datos y algoritmo (implementación de Golang) (7) Una introducción simple a la biblioteca estándar de Golang
- Estructura de datos y algoritmo (implementación de Golang) (8.1) Conocimientos básicos-Prefacio
- Estructura de datos y algoritmo (implementación de Golang) (8.2) Conocimiento básico: dividir y conquistar y recurrir
- Estructura y algoritmo de datos (implementación de Golang) (9) Complejidad del algoritmo de conocimiento básico y símbolo progresivo
- Estructura de datos y algoritmo (implementación de Golang) (10) Conocimientos básicos: el método principal de complejidad del algoritmo
- Estructuras de datos y algoritmos (implementación de Golang) (11) Estructuras de datos comunes-Prefacio
- Estructuras de datos y algoritmos (implementación de Golang) (12) Listas enlazadas de estructuras de datos comunes
- Estructuras de datos y algoritmos (implementación de Golang) (13) Estructuras de datos comunes: matrices de longitud variable
- Estructuras de datos y algoritmos (implementación de Golang) (14) Estructuras de datos comunes: pila y cola
- Estructuras de datos y algoritmos (implementación de Golang) (15) Lista de estructuras de datos comunes
- Estructuras de datos y algoritmos (implementación de Golang) (16) Estructuras de datos comunes-Diccionario
- Estructuras de datos y algoritmos (implementación de Golang) (17) Estructuras de datos comunes: árboles
- Estructura de datos y algoritmo (implementación de Golang) (18) Algoritmo de clasificación-Prefacio
- Estructura de datos y algoritmo (implementación de Golang) (19) Algoritmo de clasificación-clasificación de burbujas
- Estructura de datos y algoritmo (implementación de Golang) (20) Clasificación de algoritmos de selección
- Estructura de datos y algoritmo (implementación de Golang) (21) Clasificación de algoritmo de inserción
- Estructura de datos y algoritmo (implementación de Golang) (22) Algoritmo de clasificación-Clasificación de Hill
- Estructura de datos y algoritmo (implementación de Golang) (23) Clasificación de algoritmo de fusión
- Estructura de datos y algoritmo (implementación de Golang) (24) Algoritmo de clasificación prioritario y clasificación de montón
- Estructura de datos y algoritmo (implementación de Golang) (25) Algoritmo de clasificación: clasificación rápida
- Estructura de datos y algoritmo (implementación de Golang) (26) Tabla de algoritmo de búsqueda de hash
- Estructura de datos y algoritmo (implementación de Golang) (27) Árbol de búsqueda binario de algoritmo de búsqueda
- Estructura y algoritmo de datos (implementación de Golang) (28) Árbol de algoritmo de búsqueda-AVL
- Estructura de datos y algoritmo (implementación de Golang) (29) Árbol de algoritmo de búsqueda-2-3 y árbol rojo-negro inclinado a la izquierda
- Estructura de datos y algoritmo (implementado por Golang) (30) Árbol de algoritmo de búsqueda-2-3-4 y árbol rojo-negro ordinario