Estrutura de dados e algoritmo (implementação de Golang) (22) Algoritmo de classificação-Classificação de Hill

Hill Sort

Em 1959, um Donald L. Shell (March 1, 1924 – November 2, 2015)americano nomeado Communications of the ACM 国际计算机学会月刊lançou um algoritmo de classificação, e o algoritmo denominado classificação de Hill nasceu.

Nota: A ACM = Association for Computing MachineryInternational Computer Society, uma organização profissional mundial para profissionais de computação, fundada em 1947, é a primeira sociedade científica e educacional do mundo em computação.

A classificação em colina é uma versão aprimorada da classificação por inserção direta. Como a classificação por inserção direta é muito eficiente para as sequências que já estão quase ordenadas, ela atinge O(n)complexidade linear, mas só pode mover os dados um bit por vez. Na classificação criativa de Hill, os dados podem ser alterados um npouco e, em seguida, nsempre serão reduzidos para o mesmo que a classificação de inserção direta 1. Consulte a análise a seguir.

A classificação em colina é um algoritmo de classificação por inserção.

1. Introdução ao Algoritmo

Há uma Nsequência de números:

  1. Primeiro, pegue um Nnúmero inteiro menor que d1, d1agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique esses números diretamente.
  2. Em seguida, pegue um d1número inteiro menor que d2, d2agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique os números diretamente.
  3. Em seguida, pegue um d2número inteiro menor que d3, d3agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique os números diretamente.
  4. ...
  5. Até você obter o número inteiro d=1, use a classificação de inserção direta.

Este é um método de inserção de agrupamento.A última iteração é equivalente à classificação de inserção direta.As outras iterações são equivalentes à nclassificação de inserção direta, movendo uma distância a cada vez.Estes números inteiros são a distância entre dois números. Nós os chamamos de incremental.

Tomamos metade do comprimento da sequência como um incremento e reduzimos pela metade cada vez até que o incremento seja 1.

Como um exemplo simples, Hill classifica uma sequência de 12 elementos: [5 9 1 6 8 14 6 49 25 4 6 3]e os dvalores de incremento estão em ordem 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 完全就是直接插入排序了。

Quanto mais ordenada for a sequência, maior será a eficiência da classificação por inserção direta.A classificação de colina usa a classificação por inserção direta por agrupamento.Como o tamanho da etapa é 1maior, a sequência não ordenada pode ser rapidamente alterada para menos desordenada no início. O número de trocas também é reduzido, até que a última etapa do 1tipo de inserção direta seja usada, a sequência já esteja relativamente ordenada e, portanto, a complexidade do tempo será um pouco melhor.

Na melhor das hipóteses, quando a sequência é ordenada, a classificação de Hill precisa executar lognuma classificação de inserção direta sub incremental, porque a complexidade de tempo ideal de cada classificação de inserção direta é :, O(n)portanto, o melhor momento para a classificação de Hill O(nlogn)complexidade: .

Na pior das hipóteses, cada iteração é a pior, assumindo que a sequência incremental seja : d8 d7 d6 ... d3 d2 1, o número de elementos de classificação inseridos diretamente é : n/d8 n/d7 n/d6 .... n/d3 n/d2 n, a complexidade do tempo é calculada como a pior complexidade da inserção direta :

假设增量序列为 ⌊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)

Portanto, a pior complexidade temporal da classificação de Hill é O(n^2).

Sequências de incremento de agrupamento diferentes têm complexidade de tempo diferente, mas ninguém pode provar qual sequência é a melhor. HibbardIncremental Sequência: 1,3,7,···,2n−1uma sequência de pacotes pode ser comprovada amplamente, complexidade de tempo é: Θ(n^1.5).

A complexidade temporal da classificação de Hill é sobre esse intervalo: O(n^1.3)~O(n^2)é impossível provar estritamente pela matemática.

A classificação em subida não é estável, porque cada rodada do agrupamento usa a classificação por inserção direta, mas o agrupamento se estende por nposições, resultando em dois números idênticos, e a alteração da ordem não pode ser encontrada se a outra parte não puder ser encontrada.

2. Implementação 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)
}

Saída:

[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 acordo com vários algoritmos de classificação analisados ​​anteriormente, geralmente é recomendável usar a classificação por inserção direta quando a matriz a ser classificada for em pequena escala.A classificação em subida pode ser usada em casos de tamanho médio, mas a classificação rápida, a classificação por mesclagem ou a pilha ainda são necessárias em larga escala. Classificar.

Artigo da série

Eu sou a estrela Chen, Bem-vindo eu ter escrito, pessoalmente, estruturas de dados e algoritmos (golang conseguir) , a partir do artigo para ler mais amigável GitBook .

Acho que você gosta

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