Tri des collines
En 1959, un Donald L. Shell (March 1, 1924 – November 2, 2015)
Américain nommé a Communications of the ACM 国际计算机学会月刊
publié un algorithme de tri, et l'algorithme nommé Hill sorting est né.
Remarque: La ACM = Association for Computing Machinery
International Computer Society, une organisation professionnelle mondiale pour les praticiens de l'informatique, fondée en 1947, est la première société informatique et scientifique au monde.
Le tri en côte est une version améliorée du tri par insertion directe. Étant donné que le tri par insertion directe est très efficace pour les séquences qui sont presque déjà triées, il atteint O(n)
une complexité linéaire, mais il ne peut déplacer les données qu'un bit à la fois. Dans le tri créatif de Hill, les données peuvent être n
légèrement décalées , puis elles seront n
toujours réduites au même que le tri par insertion directe 1
. Veuillez consulter l'analyse suivante.
Le tri en côte est un algorithme de tri par insertion.
1. Introduction à l'algorithme
Il y a une N
séquence de nombres:
- Prenez d'abord un
N
entier inférieur àd1
,d1
groupez les nombres dont la position est un multiple entier dans un groupe, puis insérez et triez ces nombres directement. - Prenez ensuite un
d1
entier inférieur àd2
,d2
groupez les nombres dont la position est un multiple entier dans un groupe, puis insérez et triez les nombres directement. - Prenez ensuite un
d2
entier inférieur àd3
,d3
groupez les nombres dont la position est un multiple entier dans un groupe, puis insérez et triez les nombres directement. - ...
- Jusqu'à ce que vous obteniez l'entier
d=1
, utilisez le tri par insertion directe.
Il s'agit d'une méthode d'insertion par regroupement. La dernière itération équivaut à un tri par insertion directe. Les autres itérations sont équivalentes à n
un tri par insertion directe se déplaçant chaque fois sur une distance. Ces nombres entiers sont la distance entre deux nombres. Nous les appelons incrémentiels.
Nous prenons la moitié de la longueur de la séquence comme un incrément, puis la divisons par deux jusqu'à ce que l'incrément soit égal à 1.
Comme exemple simple, Hill trie une séquence de 12 éléments:, [5 9 1 6 8 14 6 49 25 4 6 3]
et les d
valeurs d' incrémentation sont dans l'ordre 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 完全就是直接插入排序了。
Plus la séquence est ordonnée, plus l'efficacité du tri par insertion directe est élevée. Le tri par colline utilise le tri par insertion directe par regroupement. La taille de l'étape étant 1
plus grande, la séquence non ordonnée peut être rapidement transformée en moins désordonnée au début. Le nombre d'échanges est également réduit, jusqu'à ce que la dernière étape du 1
tri par insertion directe soit utilisée, la séquence est déjà relativement ordonnée, donc la complexité temporelle sera légèrement meilleure.
Dans le meilleur des cas, c'est-à-dire lorsque la séquence est ordonnée, le tri Hill doit effectuer logn
un tri par insertion directe sous-incrémentiel, car la complexité temporelle optimale de chaque tri par insertion directe est:, O(n)
donc le meilleur moment pour le tri Hill. O(nlogn)
complexité: .
Dans le pire des cas, chaque itération est la pire, en supposant que la séquence incrémentielle est:, d8 d7 d6 ... d3 d2 1
alors le nombre d'éléments de tri directement insérés est:, n/d8 n/d7 n/d6 .... n/d3 n/d2 n
alors la complexité temporelle est calculée comme la pire complexité de l'insertion directe :
假设增量序列为 ⌊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)
Par conséquent, la pire complexité temporelle du tri Hill est O(n^2)
.
Différentes séquences d'incrément de regroupement ont une complexité temporelle différente, mais personne ne peut prouver quelle séquence est la meilleure. Hibbard
Séquence incrémentale: 1,3,7,···,2n−1
une séquence de paquets peut être largement prouvé, la complexité temporelle est: Θ(n^1.5)
.
La complexité temporelle du tri de Hill porte sur cette plage: O(n^1.3)~O(n^2)
il est impossible de le prouver strictement par les mathématiques.
Le tri en côte n'est pas stable, car chaque cycle de regroupement utilise le tri par insertion directe, mais le regroupement s'étendra sur les n
positions, résultant en deux nombres identiques, et le changement d'ordre ne pourra pas être trouvé si l'autre partie ne peut pas être trouvée.
2. Implémentation de l'algorithme
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)
}
Sortie:
[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]
Selon plusieurs algorithmes de tri analysés précédemment, il est généralement recommandé d'utiliser le tri par insertion directe lorsque le tableau à trier est à petite échelle. Le tri par colline peut être utilisé dans des cas de taille moyenne, mais un tri rapide, un tri par fusion ou un amoncellement est toujours requis à grande échelle. Trier.
Entrée d'article de série
Je suis la star Chen, bienvenue J'ai personnellement écrit des structures de données et algorithmes (golang atteindre) , à partir de l'article à lire GitBook plus convivial .
- Structure de données et algorithme (implémentation de Golang) (1) Une introduction simple à Golang-Préface
- Structures de données et algorithmes (implémentation de Golang) (2) Une introduction simple aux packages, variables et fonctions de Golang
- Structure de données et algorithme (implémentation de Golang) (3) Une introduction simple à la déclaration de contrôle du flux de Golang
- Structures de données et algorithmes (implémentation de Golang) (4) Une introduction simple aux structures et méthodes de Golang
- Structure de données et algorithme (implémentation de Golang) (5) Une introduction simple à l'interface de Golang
- Structure de données et algorithme (implémentation de Golang) (6) Une introduction simple à la concurrence de Golang, aux coroutines et aux canaux
- Structure de données et algorithme (implémentation de Golang) (7) Une introduction simple à la bibliothèque standard de Golang
- Structure et algorithme de données (implémentation de Golang) (8.1) Connaissances de base - Préface
- Structure et algorithme de données (implémentation de Golang) (8.2) Diviser et conquérir les connaissances de base et récursivité
- Structure de données et algorithme (implémentation de Golang) (9) Complexité de base de l'algorithme de connaissance et symbole progressif
- Structure des données et algorithme (implémentation de Golang) (10) Connaissances de base - la principale méthode de complexité des algorithmes
- Structures de données et algorithmes (mise en œuvre de Golang) (11) Structures de données communes-Préface
- Structures de données et algorithmes (implémentation de Golang) (12) Listes liées aux structures de données communes
- Structures de données et algorithmes (implémentation de Golang) (13) Structures de données communes - tableaux de longueur variable
- Structures de données et algorithmes (implémentation de Golang) (14) Structures de données communes - pile et file d'attente
- Structures de données et algorithmes (mise en œuvre de Golang) (15) Liste des structures de données communes
- Structures de données et algorithmes (implémentation de Golang) (16) Structures de données communes-Dictionnaire
- Structures de données et algorithmes (implémentation de Golang) (17) Structures de données communes-arbres
- Structure et algorithme de données (implémentation de Golang) (18) Algorithme de tri-Préface
- Structure des données et algorithme (implémentation de Golang) (19) Tri de l'algorithme de tri des bulles
- Structure de données et algorithme (implémentation de Golang) (20) Algorithme de tri-sélection tri
- Structure de données et algorithme (implémentation de Golang) (21) Tri par algorithme d'insertion
- Structure de données et algorithme (implémentation Golang) (22) Algorithme de tri - Tri Hill
- Structure des données et algorithme (implémentation de Golang) (23) Tri par algorithme de tri par fusion
- Structure de données et algorithme (implémentation de Golang) (24) Tri par file d'attente prioritaire et tri par tas
- Structure de données et algorithme (implémentation de Golang) (25) Tri par algorithme de tri rapide
- Structure de données et algorithme (implémentation de Golang) (26) Algorithme de recherche-Table de hachage
- Structure de données et algorithme (implémentation de Golang) (27) Arbre de recherche de l'algorithme de recherche binaire
- Structure de données et algorithme (implémentation de Golang) (28) Algorithme de recherche-arbre AVL
- Structure des données et algorithme (implémentation de Golang) (29) Trouver l'arbre de l'algorithme-2-3 et l'arbre rouge-noir de gauche
- Structure des données et algorithme (implémenté par Golang) (30) Trouver l'arbre de l'algorithme 2-3-4 et l'arbre rouge-noir ordinaire