Un tas est appelé «partiellement ordonné» et non «partiellement trié». Le mot «tri» signifie une commande complète (tri complet). Un tas n'est pas partiellement ordonné arbitrairement. Un tas est partiellement commandé après un critère (modèle), comme indiqué ci-dessous.
Ainsi, Heapsort se compose de deux étapes: construire le tas et extraire l'élément ordonné du haut du tas. Dans la deuxième étape, après chaque extraction, le tas est reconstruit. Chaque reconstruction est plus rapide que le processus de construction d'origine depuis que la reconstruction est effectuée à partir d'une version précédente, où un élément a été supprimé. Et avec cela, Heapsort trie une liste complètement non triée.
Le but de cet article est d'expliquer brièvement Heapsort, puis de produire sa complexité temporelle (voir la signification de la complexité du temps ci-dessous). Vers la fin, le codage se fait en c++.
Tas minimum
Un tas peut être un tas minimum ou un tas maximum. Un maximum-hap est celui où le premier élément est l'élément le plus élevé, et l'arbre entier ou la liste correspondante est partiellement commandé par ordre décroissant. Un min-heap est celui où le premier élément est le moins d'élément, et toute la liste est partiellement commandée par ordre croissant. Dans cet article, seul le tas minimum est considéré. Remarque: Dans le sujet du tas, un élément est également appelé nœud.
Un tas est un arbre binaire complet. L'arbre binaire peut être exprimé comme un tableau (liste); Lisez de haut en bas et de gauche à droite. La propriété du tas pour un mine-heap est qu'un nœud parent est inférieur ou égal à chacun de ses deux enfants. Un exemple de liste non ordonnée est:
9 | 19 | 24 | 5 | 3 | 11 | 14 | 22 | 7 | 6 | 17 | 15 | nul | nul | nul |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | dix | 11 | 12 | 13 | 14 |
La première rangée de ce tableau est les éléments du tableau. Dans la deuxième rangée sont les index basés sur zéro. Cette liste d'éléments peut être exprimée comme un arbre. Les éléments nuls ont été ajoutés pour faire un arbre binaire complet. À strictement parler, les éléments nuls ne font pas partie de la liste (arbre). Cette liste n'a pas d'ordre, donc ce n'est pas encore un tas. Il deviendra un tas lorsqu'il aura eu une commande partielle, selon la propriété du tas.
Relation entre les nœuds et les index
N'oubliez pas qu'un tas est un arbre binaire complet avant d'avoir la configuration du tas (propriété du tas). La liste précédente n'est pas encore un tas, car les éléments n'obéissent pas à la propriété du tas. Il devient un tas après réarrangement des éléments en ordre partiel selon la propriété Min-Heap. L'ordre partiel peut être considéré comme un type partiel (bien que le mot «tri» signifie une commande complète).
Qu'un arbre binaire soit un tas ou non, chaque parent a deux enfants, à l'exception des nœuds de feuille (dernier). Il existe une relation mathématique entre les indices entre chaque parent et ses enfants. C'est comme suit: Si le parent est à l'index I, alors l'enfant gauche est à l'index:
2 * i + 1
Et le bon enfant est à l'index:
2 * i + 2
Ceci est pour l'indexation zéro. Et donc, un parent à l'index 0 a son enfant gauche à l'index 2 × 0 + 1 = 1 et son enfant droit à 2 × 0 + 2 = 2. Un parent à l'index 1 a son enfant gauche à l'index 2 × 1 + 1 = 3 et l'enfant droit à l'index 2 × 1 + 2 = 4; et ainsi de suite.
Par la propriété Min-Heap, un parent en i est inférieur ou égal à l'enfant gauche à 2i + 1 et inférieur ou égal à l'enfant droit à 2i + 2.
Tas
Le tasage signifie construire un tas. Cela signifie réorganiser les éléments d'une liste (ou arbre correspondant) afin qu'ils satisfont la propriété du tas. À la fin du processus de tas, la liste ou l'arbre est un tas.
Si la liste précédente non triée est tasée, elle deviendra:
3 | 5 | 11 | 7 | 6 | 15 | 14 | 22 | 9 | 19 | 17 | 24 | nul | nul | nul |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | dix | 11 | 12 | 13 | 14 |
Remarque: il y a 12 éléments et non 15 dans la liste. Dans la deuxième ligne sont les index. Dans le processus de construction de tas, les éléments ont dû être vérifiés et certains échangés.
Notez que le plus petit et le premier élément est 3. Le reste des éléments suivent une manière ascendante mais ondulée. Si les enfants gauche et droit aux positions 2i + 1 et 2i + 2 sont chacun supérieurs ou égaux au parent en i, alors c'est un min-heap. Ce n'est pas une commande ou un tri complet. C'est une commande partielle, selon la propriété du tas. C'est à partir d'ici que la prochaine étape pour le tri de tas commence.
Complexité du temps
La complexité du temps est le temps d'exécution relatif d'un code. Il peut être considéré comme le nombre d'opérations principales pour que ce code termine. Il existe différents algorithmes pour la construction de tas. Le plus efficace et le plus rapide diviser en continu la liste par deux, en vérifiant les éléments par le bas, puis en faisant un échange d'éléments. Soit n le nombre d'éléments pratiques de la liste. Avec cet algorithme, le nombre maximum d'opérations principales (échange) est n. La complexité du temps pour le tasage est donnée auparavant comme:
Sur)
Où n est n et est le nombre maximal possible d'opérations principales. Cette notation est appelée la notation Big-O. Il commence par O en majuscules, suivi de parenthèses. À l'intérieur des parenthèses se trouve l'expression du plus grand nombre d'opérations possible.
N'oubliez pas: l'ajout peut devenir une multiplication si la même chose qui est ajoutée continue de répéter.
Illustration de Heapsort
La liste précédente non triée sera utilisée pour illustrer Heapsort. La liste donnée est:
9 19 24 5 3 11 14 22 7 6 17 15
Le Min-Heap produit à partir de la liste est:
3 5 11 7 6 15 14 22 9 19 17 24
La première étape de Heapsort est de produire le tas qui a été produit. Ceci est une liste partiellement commandée. Ce n'est pas une liste triée (complètement triée).
La deuxième étape consiste à retirer le moindre élément, qui est le premier élément, du tas, à réanimiser le tas restant et à retirer les moindres éléments des résultats. Le moins d'élément est toujours le premier élément du tas de réhabilation. Les éléments ne sont pas supprimés et jetés. Ils peuvent être envoyés à un tableau différent dans l'ordre dans lequel ils sont supprimés.
En fin de compte, le nouveau tableau aurait tous les éléments triés (complètement), dans l'ordre croissant; et plus seulement partiellement ordonné.
Dans la deuxième étape, la première chose à faire est d'enlever 3 et de la placer dans le nouveau tableau. Les résultats sont:
3
et
5 11 7 6 15 14 22 9 19 17 24
Les éléments restants doivent être tasés avant que le premier élément ne soit extrait. Le tas des éléments restants peut devenir:
5 6 7 9 15 14 22 11 19 17 24
L'extraction 5 et l'ajout à la nouvelle liste (tableau) donnent les résultats:
3 5
et
6 7 9 15 14 22 11 19 17 24
Le tasage de l'ensemble restant donnerait:
6 7 9 15 14 22 11 19 17 24
L'extraction 6 et l'ajout à la nouvelle liste (tableau) donnent les résultats:
3 5 6
et
7 9 15 14 22 11 19 17 24
Le tasage de l'ensemble restant donnerait:
7 9 11 14 22 15 19 17 24
Extraire 7 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7
et
9 11 14 22 15 19 17 24
Le tasage de l'ensemble restant donne:
9 11 14 22 15 19 17 24
Extraire 9 et l'ajout de la nouvelle liste donne les résultats:
3 5 6 7 9
et
11 14 22 15 19 17 24
Le tasage de l'ensemble restant donne:
11 14 17 15 19 22 24
Extraire 11 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11
et
14 17 15 19 22 24
Le tasage de l'ensemble restant donnerait:
14 17 15 19 22 24
Extraire 14 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14
et
17 15 19 22 24
Le tasage de l'ensemble restant donnerait:
15 17 19 22 24
Extraire 15 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14 15
et
17 19 22 24
Le tasage de l'ensemble restant donnerait:
17 19 22 24
Extraire 17 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14 15 17
et
19 22 24
Le tasage de l'ensemble restant donnerait:
19 22 24
Extraire 19 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14 15 17 19
et
22 24
Le tasage de l'ensemble restant donne:
22 24
Extraire 22 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14 15 17 19 22
et
24
Le tasage de l'ensemble restant donne:
24
Extraire 24 et l'ajout à la nouvelle liste donne les résultats:
3 5 6 7 9 11 14 15 17 19 22 24
et
- - -
Le tableau des tas est maintenant vide. Tous les éléments qu'il avait au début sont maintenant dans le nouveau tableau (liste) et triés.
Algorithme de tas
Bien que le lecteur ait pu lire dans les manuels que Heapsort se compose de deux étapes, Heapsort peut toujours être considéré comme composé d'une étape, qui se rétrécit itérativement du tableau donné. Avec cela, l'algorithme à trier avec Heapsort est le suivant:
Complexité du temps de Heapsort approprié
L'approche en une étape est utilisée pour déterminer la complexité temporelle de Heapsort. Supposons qu'il y a 8 éléments non triés à tri.
Le nombre maximum possible d'opérations pour haliner les 8 éléments est de 8.
Le nombre maximum possible d'opérations pour haliner les 7 éléments restants est 7.
Le nombre maximal possible d'opérations pour haliner les 6 éléments restants est 6.
Le nombre maximum possible d'opérations pour haliner les 5 éléments restants est 5.
Le nombre maximum possible d'opérations pour haliner les 4 éléments restants est 4.
Le nombre maximum possible d'opérations pour haliner les 3 éléments restants est 3.
Le nombre maximal possible d'opérations pour haliner les 2 éléments restants est 2.
Le nombre maximum d'opérations possible pour haliner l'élément 1 restant est 1.
Le nombre maximum d'opérations possible est:
8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 36
La moyenne de ce nombre d'opérations est:
36/8 = 4.5
Notez que les quatre derniers tas de l'illustration précédente n'ont pas changé, lorsque le premier élément a été supprimé. Certains des tas précédents n'ont pas également changé lorsque le premier élément a été supprimé. Avec cela, un meilleur nombre moyen d'opérations principales (échanges) est de 3 et non 4.5. Ainsi, un meilleur nombre total d'opérations principales est:
24 = 8 x 3
=> 24 = 8 x journal28
Depuis le journal28 = 3.
En général, la complexité moyenne du temps de cas pour Heapsort est:
Sur.log2n)
Lorsque le DOT signifie multiplication et n est n, le nombre total d'éléments dans la liste (soit la liste).
Notez que le fonctionnement de l'extraction du premier élément a été ignoré. Sur le thème de la complexité du temps, les opérations qui prennent des temps relativement courtes sont ignorées.
Codage en c++
Dans la bibliothèque d'algorithme de C ++, il y a une fonction Make_heap (). La syntaxe est:
modèle
Consxpr void Make_Heap (RandomAccesIterator First, RandomAccesSiterator Last, Compare Compci);
Il prend l'itérateur pointant vers le premier élément d'un vecteur comme premier argument, puis l'itérateur pointant juste au-delà de la fin du vecteur comme dernier argument. Pour la liste précédente non triée, la syntaxe serait utilisée comme suit pour obtenir un tas minimum:
vecteurvtr = 9, 19, 24, 5, 3, 11, 14, 22, 7, 6, 17, 15;
vecteur:: iterator iterb = vtr.commencer();
vecteur:: iterator itere = vtr.fin();
Make_heap (iterb, itere, plus grand());
Ce code modifie un contenu vectoriel en une configuration de tas minimale. Dans les vecteurs C ++ suivants, deux vecteurs seront utilisés à la place de deux tableaux.
Pour copier et retourner le premier élément d'un vecteur, utilisez la syntaxe vectorielle:
CONSEXPR Front ();
Pour supprimer le premier élément d'un vecteur et jetez-le, utilisez la syntaxe vectorielle:
constexpr iterator effacer (position const_iterator)
Pour ajouter un élément à l'arrière d'un vecteur (élément suivant), utilisez la syntaxe vectorielle:
constexpr void push_back (const t & x);
Le début du programme est:
#inclure
#inclure
#inclure
Utilisation de Namespace Std;
L'algorithme et les bibliothèques vectorielles sont incluses. Le programme est la fonction Heapsort (), qui est:
vide heapsort (vecteur& Oldv, vecteur & newv)
if (oldv.size ()> 0)
vecteur:: iterator iterb = oldv.commencer();
vecteur:: iterator itere = oldv.fin();
Make_heap (iterb, itere, plus grand());
int next = oldv.devant();
OldV.effacer (iterb);
NewV.push_back (suivant);
Heapsort (Oldv, Newv);
C'est une fonction récursive. Il utilise la fonction Make_heap () de la bibliothèque de l'algorithme C ++. Le deuxième segment de code de la définition de fonction extrait le premier élément de l'ancien vecteur après le bâtiment du tas et ajoute comme l'élément suivant pour le nouveau vecteur. Notez que dans la définition de la fonction, les paramètres vectoriels sont des références, tandis que la fonction est appelée avec les identifiants (noms).
Une fonction principale C ++ appropriée pour cela est:
int main (int argc, char ** argv)
vecteurOLDV = 9, 19, 24, 5, 3, 11, 14, 22, 7, 6, 17, 15;
vecteurNewv;
Heapsort (Oldv, Newv);
pour (int i = 0; icouter << newV[i] << ";
couter << endl;
retour 0;
La sortie est:
3 5 6 7 9 11 14 15 17 19 22 24
trié (complètement).
Conclusion
L'article discuté en détail la nature et la fonction du tri de tas communément appelées heapsort, comme un algorithme de tri. La complexité du temps de tas, l'illustration de Heapsort et le tastral en tant qu'algorithme ont été couvertes et soutenues par des exemples. La complexité du temps moyenne pour un programme de heapsort bien écrit est O (nlog (n))