Exercice 2 (5 points) — dans l'esprit des sessions principales 2021 et 2026
Soit TAB un nouveau type tableau de 100 entiers. On considère la procédure Saisie suivante, qui remplit un tableau T de type TAB par N entiers (5 ≤ N ≤ 100) :
Procédure Saisie (@T : TAB, N : Entier)
DEBUT
Répéter
Ecrire("T[0] = ")
Lire(T[0])
Jusqu'à T[0] ≥ 0
Pour i de 1 à N-1 Faire
Répéter
Ecrire("T[", i, "] = ")
Lire(T[i])
Jusqu'à T[i] > T[i-1]
Fin Pour
FINOn se propose de vérifier si un entier x donné figure dans le tableau T ainsi rempli, puis de déterminer où il faudrait l'insérer.
Fonction Existe (à compléter à la question 2) :
Fonction Existe (T : TAB, N, x : Entier)
: Booléen
DEBUT
g ← ……
d ← ……
Répéter
m ← ……………
Si T[m] < x Alors
……………
Sinon Si T[m] > x Alors
……………
FinSi
Jusqu'à (T[m] = x) Ou (……………)
Retourner ……………
FINT.D.O.L. de Existe : Objet …… | Type/Nature ……
Tableau T utilisé aux questions 3 et 4 (N = 9) :
indice : 0 1 2 3 4 5 6 7 8
T : 3 8 11 17 24 30 36 45 52Travail demandé :
- Concernant la procédure Saisie :
- Donner le rôle de la procédure Saisie.
- Quelle caractéristique présente le tableau T rempli par Saisie pour privilégier la recherche dichotomique à la recherche séquentielle ?
- Un élève affirme qu'on peut appliquer la recherche dichotomique à un tableau quelconque, sans le trier au préalable. Corriger cette affirmation.
- Compléter l'algorithme de la fonction booléenne Existe, qui exploite le principe de la recherche dichotomique pour vérifier si x figure dans T, puis compléter son T.D.O.L.
- On exécute Existe(T, 9, x) avec le tableau T ci-dessus.
- Pour x = 45, donner les valeurs successives de g, d et m à chaque passage dans la boucle, et la valeur retournée.
- Même question pour x = 20.
- Pour un tableau de N = 100 entiers, combien de passages dans la boucle la fonction Existe effectue-t-elle au plus ? Combien de comparaisons avec x une recherche séquentielle peut-elle demander ?
- On se propose d'écrire une fonction PosInsert(T, N, x) qui retourne la position d'insertion de x, c'est-à-dire l'indice de la première case de T dont le contenu est strictement supérieur à x : c'est là qu'il faudrait insérer x pour que T reste dans l'ordre croissant. La valeur retournée doit être égale à N pour toute valeur de x ≥ T[N−1].
- Pour le tableau T ci-dessus, donner la valeur retournée par PosInsert pour x = 20, x = 24 et x = 60.
- En modifiant la fonction Existe, écrire l'algorithme de la fonction PosInsert, sans parcours séquentiel du tableau, et dresser son T.D.O.L.
- (Section Sciences de l'informatique — approfondissement ; les autres sections peuvent s'arrêter à la question 4.) Écrire l'algorithme d'une fonction récursive RechRec(T, g, d, x) qui retourne Vrai si x figure dans la partie de T délimitée par les indices g et d, Faux sinon, selon le même principe. Donner l'instruction qui remplace Existe(T, N, x).
N.B. Les cases d'un tableau sont indicées à partir de 0.
Voir la correction commentéeAprès avoir posé votre démarche
1.a Idée : lire la condition d'arrêt de chaque boucle Répéter. La procédure Saisie remplit T par N entiers : le premier positif ou nul, chacun des suivants strictement supérieur au précédent ; la saisie d'une case est reprise tant que cette condition n'est pas vérifiée.
1.b Le tableau T est trié dans l'ordre strictement croissant : T[i] > T[i−1] pour tout i de 1 à N−1. Comparer x à la case du milieu permet alors d'écarter toute une moitié du tableau (si T[m] > x, x ne peut se trouver qu'à gauche de m).
1.c L'affirmation est fausse : la recherche dichotomique s'applique à un tableau trié ; un tableau quelconque doit d'abord être trié, sinon on utilise la recherche séquentielle, applicable à tout tableau. Sur un tableau non trié, la comparaison avec la case du milieu ne dit plus de quel côté se trouve x : écarter une moitié peut écarter justement la case qui le contient.
2. Idée : la partie [g, d] contient toujours les cases où x peut encore se trouver ; elle part du tableau entier (indices 0 à N − 1) et exclut à chaque passage le milieu déjà comparé.
Fonction Existe (T : TAB, N, x : Entier)
: Booléen
DEBUT
g ← 0
d ← N - 1
Répéter
m ← (g + d) Div 2
Si T[m] < x Alors
g ← m + 1
Sinon Si T[m] > x Alors
d ← m - 1
FinSi
Jusqu'à (T[m] = x) Ou (g > d)
Retourner T[m] = x
FINT.D.O.L. de Existe : g, d, m — Type/Nature : Entier.
La boucle Répéter s'exécute au moins une fois, ce qui est possible puisque N ≥ 5. À la sortie, soit T[m] = x, soit g > d (partie vide) et alors T[m] ≠ x : retourner la valeur de l'expression T[m] = x donne la bonne réponse dans les deux cas.
3.a Idée : une ligne par passage, avec les bornes après la mise à jour.
passage m T[m] g d
début - - 0 8
1 4 24 5 8
2 6 36 7 8
3 7 45 7 8T[7] = 45 = x : arrêt après 3 passages, Existe retourne .
3.b
passage m T[m] g d
début - - 0 8
1 4 24 0 3
2 1 8 2 3
3 2 11 3 3
4 3 17 4 3Après le 4ᵉ passage, g = 4 > d = 3 : la partie est vide. T[3] = 17 ≠ 20, Existe retourne ; 20 se placerait entre T[3] = 17 et T[4] = 24.
3.c Idée : un passage sans succès laisse au plus la moitié des cases restantes. Sur k cases restantes, il en reste au plus k Div 2 : 100, 50, 25, 12, 6, 3, 1. Le septième passage examine la dernière case possible, d'où au plus passages (). Une recherche séquentielle peut demander 100 comparaisons (x absent ou dans la dernière case).
4.a Idée : chercher la première case strictement supérieure à x.
- x = 20 : la première case > 20 est T[4] = 24, d'où .
- x = 24 : T[4] = 24 n'est pas strictement supérieur à 24 ; la première case > 24 est T[5] = 30, d'où .
- x = 60 ≥ T[8] = 52 : aucune case ne convient, PosInsert retourne N, soit .
4.b Idée : on ne s'arrête plus quand T[m] = x ; une case égale à x n'est pas « strictement supérieure », on continue donc à droite. La boucle ne s'arrête que sur la partie vide ; alors g = d + 1, toutes les cases d'indice inférieur à g contiennent une valeur ≤ x et toutes celles d'indice supérieur à d une valeur > x : g est la position cherchée.
Fonction PosInsert (T : TAB,
N, x : Entier) : Entier
DEBUT
g ← 0
d ← N - 1
Tant que g ≤ d Faire
m ← (g + d) Div 2
Si T[m] > x Alors
d ← m - 1
Sinon
g ← m + 1
FinSi
Fin Tant que
Retourner g
FINT.D.O.L. de PosInsert : g, d, m — Type/Nature : Entier.
Contrôle sur T : pour x = 24, m prend les valeurs 4 (24 ≤ 24, g = 5), 6 (36 > 24, d = 5) puis 5 (30 > 24, d = 4) et la fonction retourne 5. Pour x = 60, g passe à 5, 7, 8 puis 9 = N : la valeur exigée pour x ≥ T[N−1] est obtenue sans cas particulier.
5. Idée : deux cas d'arrêt — partie vide (Faux) ou milieu égal à x (Vrai) ; sinon un seul appel récursif, sur la moitié qui peut contenir x. Le test g > d vient en premier : sur une partie vide, on ne lit aucune case.
Fonction RechRec (T : TAB,
g, d, x : Entier) : Booléen
DEBUT
Si g > d Alors
Retourner Faux
Sinon
m ← (g + d) Div 2
Si T[m] = x Alors
Retourner Vrai
Sinon Si T[m] > x Alors
Retourner RechRec(T, g, m-1, x)
Sinon
Retourner RechRec(T, m+1, d, x)
FinSi
FinSi
FINT.D.O.L. de RechRec : m — Type/Nature : Entier.
L'instruction RechRec(T, 0, N-1, x) remplace Existe(T, N, x). Pour x = 20, les appels portent sur (g, d) = (0, 8), (0, 3), (2, 3), (3, 3), puis (4, 3), qui retourne Faux.