Tas binaire![]() ![]() En informatique, un tas binaire est une structure de données utilisée notamment pour implémenter une file de priorité car elle permet de retirer l’élément de priorité maximale (resp. minimale) d'un ensemble ou d’insérer un élément dans l'ensemble en temps logarithmique tout en conservant la structure du tas binaire[1]. On peut la représenter par un arbre binaire qui vérifie ces deux contraintes :
Si la relation d'ordre choisie est "supérieure ou égale", on parle alors de tas-max (ou max-heap). Si la relation est "inférieure ou égale", on parle alors de tas-min (ou min-heap). HistoriqueLe tas binaire a été introduit par J. W. J. Williams (en) en 1964, en tant que structure de données pour le tri en tas[2]. ImplémentationUn tas binaire est un arbre binaire parfait. On peut donc l'implémenter, de manière compacte, avec un tableau :
![]() Parfois, dans un souci d'efficacité, on ignore l'indice 0 et place la racine à l'indice 1. Ainsi les indices des fils d'un nœud à l'index sont et et l'indice du père est . L'avantage est que le calcul de ces indices peut se faire simplement par des opérations logiques de décalage de bits, ce qui est plus efficace en pratique que des opérations arithmétiques. OpérationsUn tas binaire supporte les opérations suivantes :
AjouterConsidérons que l'on veuille ajouter le nœud à notre tas binaire :
Soit la hauteur de notre tas binaire. Lors de l'algorithme ci-dessus on effectue au plus échanges. Or, comme un tas binaire est un arbre binaire parfait, on a , avec le nombre de nœuds du tas binaire et une constante. La complexité est donc bien en . Exemple : On insère 50 dans un tas-max. On insère 50 à la position libre la plus à gauche. On compare 50 et son père 28. Comme 50 > 28, on échange les positions de 50 et de 28. On compare 50 et son père 41. Comme 50 > 41, on échange les positions de 50 et 41. On compare 50 et son père 53. Comme 50 < 53, on n'échange pas les positions de 50 et 53, et on a fini de modifier notre arbre. Il respecte à présent toutes les contraintes d'un arbre binaire. RetirerComplexité : On souhaite retirer la racine de notre tas binaire (c'est-à-dire le maximum de notre tas selon la relation d'ordre associée). Cependant, il faut là aussi conserver la structure de tas binaire après la suppression. On procède donc de la manière suivante :
Par le même argument que pour l'algorithme de ajouter, on fait au plus échanges donc la complexité est bien Exemple : On retire la racine du tas-max suivant : On remplace donc la racine par le nœud en dernière position (ici, 20). On compare 20 et son fils maximum, qui est 41. Comme 41 > 20, on échange 20 et 41. On compare 20 et son fils maximum, qui est 36. Comme 36 > 20, on échange 20 et 36. On compare 20 et son fils maximum, qui est 31. Comme 31 > 20, on échange 20 et 31. 20 n'a plus de fils, on a donc fini. Les propriétés d'ordre et de structure du tas sont rétablies. Augmenter ou diminuer une cléOn peut augmenter ou diminuer la priorité (la clé) d'un nœud mais il faut ensuite satisfaire la contrainte d'ordre. Si l'on augmente la clé on fera donc un percolate-up à partir de notre nœud et si l'on diminue la clé on fera un percolate-down. Percolate-upComplexité : où est la profondeur de On augmente la clé de notre nœud , par conséquent il se peut qu'il devienne supérieur à son père et à d'autres nœuds au-dessus de son père. Pour maintenir la contrainte d'ordre on effectue donc l'opération suivante : tant que n'est pas la racine et est strictement supérieur à son père on échange les positions entre et son père. Percolate-downComplexité : où est la profondeur de et la hauteur de l'arbre On diminue la clé de notre nœud , il se peut donc qu'il devienne inférieur à un de ses fils et à d'autres nœuds en dessous. Pour maintenir la contrainte d'ordre on effectue donc l'opération suivante : tant que a des fils et est strictement inférieur à un de ses fils on échange les positions entre et son fils maximum. ConstruireComplexité : On souhaite construire un tas binaire à partir d'un ensemble d'éléments. De manière naïve on part du tas vide et on ajoute les éléments un par un avec l'algorithme ajouter, ce qui donne une complexité en . Ce n'est pas optimal, il existe une manière de construire notre tas binaire en [3]: 1. On construit un arbre binaire parfait avec tous les éléments sans se soucier de la contrainte d'ordre. Cela prend donc un temps linéaire en . 2. On parcourt les sommets niveau par niveau en partant de l'avant dernier niveau (profondeur ) et dans chaque niveau on parcourt les sommets de la droite vers la gauche. Lors de notre parcours on effectue un percolate-down à partir de chaque sommet. Preuve de la correctionOn convient d'appeler sous-arbre d'un sommet dans un arbre le sous-arbre maximal dont ce sommet est la racine. Pendant le parcours des sommets on maintient l'invariant suivant : Tous les sous-arbres des sommets à droite du sommet courant (sur le même niveau) sont des tas binaires. Donc après avoir traité la racine, comme elle vérifie l'invariant, notre arbre est un tas binaire. Preuve de la complexitéSoit la hauteur de notre arbre (il y a donc niveaux qui vont de à ) et le nombre de sommets.
Dans le pire cas, chaque percolate-down effectue le nombre maximal d'échange qui est . Le coût total de construire est donc majoré par . Par le changement de variable dans la somme on obtient : . Références
Liens externes |
Portal di Ensiklopedia Dunia