Adloun

Un tas maximum sans réécrire une ligne

Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 11 — Arbres de recherche, tas et files de priorité

Énoncé

On dispose d'un tas minimum sur des int et l'on veut une file de priorité qui serve le plus grand d'abord. Un étudiant propose d'insérer au lieu de , et de rendre l'opposé du minimum extrait. Le procédé est-il correct ? Y a-t-il un cas où il échoue ?

Corrigé

Le procédé est correct presque toujours, et son unique défaut est instructif.

Pourquoi il marche. renverse l'ordre : . Le minimum des est donc l'opposé du maximum des , et l'invariant de tas minimum sur les opposés est exactement l'invariant de tas maximum sur les valeurs. Aucune ligne du code n'est à changer.

Où il échoue. Sur un type entier signé, l'intervalle n'est pas symétrique : mesuré, INT_MIN vaut et INT_MAX vaut . L'opposé de INT_MIN n'est pas représentable : c'est un dépassement signé, donc un comportement indéfini. Mesuré sur cette machine, -INT_MIN rend INT_MIN lui-même ; sur int8_t, -(-128) rend . Insérer INT_MIN dans le tas négatif y insérerait donc INT_MIN, la plus petite valeur au lieu de la plus grande : elle sortirait en premier au lieu de sortir en dernier.

Trois parades, par ordre de préférence.

C'est le dépassement d'entier silencieux du chapitre chap:langage-c, reparu là où on ne le cherchait plus : une transformation qui préserve l'ordre mathématique ne préserve pas forcément l'ordre machine.

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.