Estructura de datos y algoritmo (implementación de Golang) (22) Algoritmo de clasificación-Clasificación de Hill

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 MachineryInternational 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 npoco y luego nsiempre 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 Nsecuencia de números:

  1. Primero tome un Nnúmero entero menor que d1, d1agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique estos números directamente.
  2. Luego tome un d1número entero menor que d2, d2agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique los números directamente.
  3. Luego tome un d2número entero menor que d3, d3agrupe los números cuya posición es un múltiplo entero en un grupo, e inserte y clasifique los números directamente.
  4. ...
  5. 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 nla 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 dvalores 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 1será 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 1se 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 lognuna 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 1entonces el número de elementos de clasificación insertados directamente es :, n/d8 n/d7 n/d6 .... n/d3 n/d2 nentonces 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. HibbardIncremental de secuencia: 1,3,7,···,2n−1una 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á nposiciones, 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 .

Supongo que te gusta

Origin www.cnblogs.com/nima/p/12724858.html
Recomendado
Clasificación