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 Machinery
International 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 n
pouco e, em seguida, n
sempre 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 N
sequência de números:
- Primeiro, pegue um
N
número inteiro menor qued1
,d1
agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique esses números diretamente. - Em seguida, pegue um
d1
número inteiro menor qued2
,d2
agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique os números diretamente. - Em seguida, pegue um
d2
número inteiro menor qued3
,d3
agrupe os números cuja posição é um múltiplo inteiro em um grupo e insira e classifique os números diretamente. - ...
- 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 à n
classificaçã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 d
valores 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 é 1
maior, 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 1
tipo 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 logn
uma 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. Hibbard
Incremental Sequência: 1,3,7,···,2n−1
uma 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 n
posiçõ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 .
- Estrutura de dados e algoritmo (implementação Golang) (1) Uma introdução simples ao Golang-Prefácio
- Estruturas e algoritmos de dados (implementação Golang) (2) Uma introdução simples aos pacotes, variáveis e funções Golang
- Estrutura de dados e algoritmo (implementação de Golang) (3) Uma introdução simples à declaração de controle de fluxo de Golang
- Estruturas de dados e algoritmos (implementação de Golang) (4) Uma introdução simples às estruturas e métodos de Golang
- Estrutura e algoritmo de dados (implementação Golang) (5) Uma introdução simples à interface Golang
- Estrutura e algoritmo de dados (implementação Golang) (6) Uma introdução simples à simultaneidade, corotinas e canais de Golang
- Estrutura e algoritmo de dados (implementação Golang) (7) Uma introdução simples à biblioteca padrão Golang
- Estrutura de dados e algoritmo (implementação de Golang) (8.1) Conhecimento básico-Prefácio
- Estrutura de dados e algoritmo (implementação de Golang) (8.2) Conhecimento básico - divisão, conquista e recursão
- Estrutura e algoritmo dos dados (implementação Golang) (9) Complexidade básica do algoritmo do conhecimento e símbolo progressivo
- Estrutura de dados e algoritmo (implementação de Golang) (10) Conhecimento básico - o principal método de complexidade de algoritmos
- Estruturas de dados e algoritmos (implementação de Golang) (11) Estruturas de dados comuns - Prefácio
- Estruturas e algoritmos de dados (implementação Golang) (12) Listas comuns vinculadas a estruturas de dados
- Estruturas e algoritmos de dados (implementação Golang) (13) Matrizes comuns de estruturas de comprimento variável
- Estruturas e algoritmos de dados (implementação de Golang) (14) Estruturas de dados comuns - pilha e fila
- Estruturas de dados e algoritmos (implementação de Golang) (15) Lista comum de estruturas de dados
- Estruturas de dados e algoritmos (implementação de Golang) (16) Dicionário de estruturas de dados comum
- Estruturas e algoritmos de dados (implementação de Golang) (17)
- Estrutura de dados e algoritmo (implementação de Golang) (18) Algoritmo de classificação-Prefácio
- Estrutura e algoritmo de dados (implementação Golang) (19) Classificação de algoritmos de classificação por bolhas
- Estrutura de dados e algoritmo (implementação Golang) (20) Classificação de seleção de algoritmo de classificação
- Estrutura e algoritmo de dados (implementação Golang) (21) Classificação de inserção de algoritmo de classificação
- Estrutura de dados e algoritmo (implementação de Golang) (22) Algoritmo de classificação-Classificação de Hill
- Estrutura e algoritmo de dados (implementação Golang) (23) Classificação de algoritmo de mesclagem
- Estrutura e algoritmo de dados (implementação Golang) (24) Classificação da fila de prioridade do algoritmo e classificação da pilha
- Estrutura e algoritmo de dados (implementação Golang) (25) Classificação rápida por algoritmo de classificação
- Estrutura de dados e algoritmo (implementação de Golang) (26) Tabela de algoritmos e hash de pesquisa
- Estrutura e algoritmo dos dados (implementação Golang) (27) Árvore de pesquisa binária do algoritmo de pesquisa
- Estrutura e algoritmo dos dados (implementação Golang) (28) Árvore de algoritmo de pesquisa-AVL
- Estrutura e algoritmo de dados (implementação de Golang) (29) Localização da árvore do algoritmo-2-3 e da árvore vermelha e preta inclinada para a esquerda
- Estrutura e algoritmo de dados (implementado por Golang) (30) Localização da árvore do algoritmo-2-3-4 e da árvore comum de vermelho-preto