Tri de l'arbre - Tree sort
Classer | Algorithme de tri |
---|---|
Structure de données | Déployer |
Performances dans le pire des cas | O ( n ²) (asymétrique) O ( n log n ) (équilibré) |
Le meilleur cas la performance | O ( n log n ) |
Performances moyennes | O ( n log n ) |
Complexité spatiale dans le pire des cas | ( n ) |
Un tri par arbre est un algorithme de tri qui construit un arbre de recherche binaire à partir des éléments à trier, puis parcourt l'arbre ( dans l'ordre ) de sorte que les éléments sortent dans l'ordre trié. Son utilisation typique est le tri des éléments en ligne : après chaque insertion, l'ensemble des éléments vus jusqu'à présent est disponible dans l'ordre trié.
Le tri par arborescence peut être utilisé comme tri ponctuel, mais il est équivalent au tri rapide car les deux partitions récursivement les éléments en fonction d'un pivot, et puisque le tri rapide est en place et a moins de frais généraux, il présente peu d'avantages par rapport au tri rapide. Il a une meilleure complexité dans le pire des cas lorsqu'un arbre d'auto-équilibrage est utilisé, mais encore plus de frais généraux.
Efficacité
L'ajout d'un élément à un arbre de recherche binaire est en moyenne un processus O (log n ) (en grande notation O ). L'ajout de n éléments est un processus O ( n log n ) , faisant du tri par arborescence un processus de « tri rapide ». L'ajout d'un élément à un arbre binaire déséquilibré nécessite O ( n ) temps dans le pire des cas : lorsque l'arbre ressemble à une liste chaînée ( arbre dégénéré ). Il en résulte dans le pire des cas de O ( n ²) du temps pour cet algorithme de tri. Ce pire cas se produit lorsque l'algorithme opère sur un ensemble déjà trié, ou presque trié, inversé ou presque inversé. Le temps O ( n log n ) attendu peut cependant être atteint en mélangeant le tableau, mais cela n'aide pas pour des éléments égaux.
Le comportement dans le pire des cas peut être amélioré en utilisant un arbre de recherche binaire à équilibrage automatique . En utilisant un tel arbre, l'algorithme a une performance dans le pire des cas O ( n log n ) , ce qui en fait un degré optimal pour un tri par comparaison . Cependant, les algorithmes de tri d'arborescence nécessitent l'allocation de mémoire séparée pour l'arborescence, contrairement aux algorithmes sur place tels que quicksort ou heapsort . Sur la plupart des plates-formes courantes, cela signifie que la mémoire de tas doit être utilisée, ce qui représente un impact significatif sur les performances par rapport à quicksort et heapsort . Lors de l'utilisation d'un arbre splay comme arbre de recherche binaire, l'algorithme résultant (appelé splaysort ) a la propriété supplémentaire qu'il s'agit d'un tri adaptatif , ce qui signifie que son temps d'exécution est plus rapide que O ( n log n ) pour les entrées qui sont presque triées.
Exemple
L'algorithme de tri arborescent suivant en pseudocode accepte une collection d'éléments comparables et génère les éléments dans l'ordre croissant :
STRUCTURE BinaryTree
BinaryTree:LeftSubTree
Object:Node
BinaryTree:RightSubTree
PROCEDURE Insert(BinaryTree:searchTree, Object:item)
IF searchTree.Node IS NULL THEN
SET searchTree.Node TO item
ELSE
IF item IS LESS THAN searchTree.Node THEN
Insert(searchTree.LeftSubTree, item)
ELSE
Insert(searchTree.RightSubTree, item)
PROCEDURE InOrder(BinaryTree:searchTree)
IF searchTree.Node IS NULL THEN
EXIT PROCEDURE
ELSE
InOrder(searchTree.LeftSubTree)
EMIT searchTree.Node
InOrder(searchTree.RightSubTree)
PROCEDURE TreeSort(Collection:items)
BinaryTree:searchTree
FOR EACH individualItem IN items
Insert(searchTree, individualItem)
InOrder(searchTree)
Dans une forme de programmation fonctionnelle simple , l'algorithme (en Haskell ) ressemblerait à ceci :
data Tree a = Leaf | Node (Tree a) a (Tree a)
insert :: Ord a => a -> Tree a -> Tree a
insert x Leaf = Node Leaf x Leaf
insert x (Node t y s)
| x <= y = Node (insert x t) y s
| x > y = Node t y (insert x s)
flatten :: Tree a -> [a]
flatten Leaf = []
flatten (Node t x s) = flatten t ++ [x] ++ flatten s
treesort :: Ord a => [a] -> [a]
treesort = flatten . foldr insert Leaf
Dans la mise en œuvre ci-dessus, à la fois l'algorithme d'insertion et l'algorithme de récupération ont O ( n ²) des pires scénarios.
Liens externes
- Applet Java Binary Tree et explication sur la Wayback Machine (archivé le 29 novembre 2016)
- Tri arborescent d'une liste chaînée
- Tri d'arbres en C++