heap
) en C++¶La standard template library (STL) fournit les fonctionalités d'un tas via un ensemble de fonctions de la librairie <algorithm>
Fonction | Description |
---|---|
std::push_heap |
ajoute un élément dans un tas |
std::pop_heap |
supprime l'élément au sommet d'un tas |
std::make_heap |
crée un tas à partir d'un tableau quelconque |
std::sort_heap |
trie les éléments à partir d'un tas |
std::is_heap |
vérifie si les éléments respectent la condition de tas |
std::is_heap_until |
trouve le premier élément ne respectant pas la condition de tas |
Ces fonctions ont toutes le même prototype.
Soit la version générale
template <class RandomAccessIterator, class Compare>
void xxx_heap (RandomAccessIterator first,
RandomAccessIterator last,
Compare comp);
qui prend en entrée
[first,last[
template <typename T>
bool comp(const T& a, const T& b) {
return a < b;
}
Soit la version simple
template <class RandomAccessIterator>
void xxx_heap (RandomAccessIterator first,
RandomAccessIterator last);
qui utilise T::operator<(const T&)
pour comparer des éléments de type T
.
La fonction is_heap
retourne évidemment un bool
,
et is_heap_until
retourne un itérateur.
L'interface basé sur des itérateurs a comme conséquence que
Observons leurs effets
// Créer le tas
std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8 };
std::make_heap(v.begin(),v.end());
v
{ 8, 5, 7, 4, 1, 6, 3, 2 }
// Ajouter l'élément 9 au vecteur
v.push_back(9);
v
{ 8, 5, 7, 4, 1, 6, 3, 2, 9 }
// Placer le dernier élément dans le tas
std::push_heap(v.begin(),v.end());
v
{ 9, 8, 7, 5, 1, 6, 3, 2, 4 }
// Placer le sommet en queue du tas et rétablir le tas pour les autres éléments
std::pop_heap(v.begin(),v.end());
v
{ 8, 5, 7, 4, 1, 6, 3, 2, 9 }
// supprimer le dernier élément
v.pop_back();
v
{ 8, 5, 7, 4, 1, 6, 3, 2 }
// Trier à partir du tas v
std::sort_heap(v.begin(),v.end());
v
{ 1, 2, 3, 4, 5, 6, 7, 8 }
// vérifier si c'est un tas
std::cout << std::is_heap(v.begin(),v.end());
false
// Trouver le premier élément plus grand que son parent
std::cout << *(std::is_heap_until(v.begin(),v.end()));
2
Pour que ces fonctions s'exécutent correctement, il est essentiel que les pré-conditions soient respectées.
Fonctions | Pré-condition |
---|---|
std::pop_heap(first,last) std::sort_heap(first,last) |
[first,last[ respecte la condition de tas |
std::push_heap(first,last) |
[first,last-1[ respecte la condition de tas |
Sinon, l'algorithme est appliqué
push_heap
) pop_heap
et sort_heap
)mais le résultat final n'est pas nécessairement
push_heap
et pop_heap
)sort_heap
)// ajout dans un tas incorrect
v.assign({ 1, 2, 3, 4, 5, 6, 7 });
std::push_heap(v.begin(),v.end());
std::cout << std::is_heap(v.begin(),v.end());
v
false
{ 7, 2, 1, 4, 5, 6, 3 }
// suppression d'un tas incorrect
v.assign({ 1, 2, 3, 4, 5, 6, 7 });
std::pop_heap(v.begin(),v.end());
std::cout << std::is_heap(v.begin(),v.end()-1);
v
false
{ 7, 2, 3, 4, 5, 6, 1 }
// tri à partir d'une séquence pas en tas
v.assign({ 1, 2, 3, 4, 5, 6, 7 });
std::sort_heap(v.begin(),v.end());
v
{ 2, 3, 4, 5, 6, 7, 1 }
© Olivier Cuisenaire, 2018 |