L'arithmétique du tas dans un tableau
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 11 — Arbres de recherche, tas et files de priorité
Énoncé
Le tas du chapitre est rangé aux indices à .
- Quel est le père de l'indice ? Quels sont les fils de l'indice ?
- Le tableau est-il un tas minimum ? Sinon, exhiber la violation.
- Dans
inserer, la boucle testei > 0 && t[i] < t[(i - 1) / 2]. Que se passe-t-il si l'on retire la gardei > 0— en C, puis dans un langage où la division entière arrondit vers ?
Corrigé
1. Le père de est , qui porte ; les fils de sont et , qui portent et . On vérifie , , : l'invariant tient.
2. Non. Mesuré : . L'indice est bien un fils de (), et le tas exige . La forme, elle, est correcte — six cases contiguës — mais l'ordre ne l'est pas.
3. C'est la question qui piège, et la réponse dépend du langage.
- En C, mesuré :
(0 - 1) / 2vaut , car la division entière de C99 tronque vers zéro. À on comparerait donct[0] < t[0], qui est faux, et la boucle s'arrêterait. Le code marcherait — par accident. C'est le pire des cas de figure : une garde qui semble inutile parce que la faute qu'elle prévient est masquée par une convention d'arrondi. - Dans un langage où la division arrondit vers — Python, où mesuré
(0-1)//2vaut — l'indice désigne la dernière case du tableau. On comparerait la racine avec le dernier élément, et l'on pourrait les échanger : le tas serait corrompu, silencieusement. - Et si l'on écrit le père par décalage,
(i - 1) >> 1— une optimisation courante —, alors mesuré en C :(-1) >> 1vaut , car le décalage à droite d'un entier signé est arithmétique. On liraitt[-1], hors du tableau : comportement indéfini.
La leçon : i > 0 n'est pas une précaution, c'est la précondition de « le père de existe ». On l'écrit parce qu'elle est vraie du problème, jamais parce qu'un test l'a rendue nécessaire.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.