Adloun

informatique (MP2I/MPI) · Chapitre 11 · Application directe du cours

L'arithmétique du tas dans un tableau

Arbres de recherche, tas et files de priorité · niveau 2

É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 teste i > 0 && t[i] < t[(i - 1) / 2]. Que se passe-t-il si l'on retire la garde i > 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) / 2 vaut , car la division entière de C99 tronque vers zéro. À on comparerait donc t[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)//2 vaut — 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) >> 1 vaut , car le décalage à droite d'un entier signé est arithmétique. On lirait t[-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.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre