Vous êtes sur la page 1sur 7

L2 Informatique Algorithmique et Structures de données 2017-2018

Corrigé Examen (Durée 1.5 h)


Documents et Téléphones Portables Interdits.

Exercice1 (0.5 + 0.5 + 1 + 1 + 1 + 1 + 1 = 6 points):


Soit R un Arbre Binaire de Recherche (ABR) contenant des entiers. Son parcours en largeur (par niveau)
de gauche à droite donne le résultat suivant : 35, 20, 55, 5, 30, 45, 60, 25, 33.
1. Donner la représentation graphique de cet arbre R.

2. Donner le résultat du parcours préordre et postordre de l’arbre R


Préordre (0.25) : 35, 20, 5, 30, 25, 33, 55, 45, 60
Postordre (0.25) : 5, 25, 33, 30, 20, 45, 60, 55, 35
3. L’arbre R est-il strictement binaire ? est-il complet ? (Justifier votre réponse)
Réponse (2 * Justification (2 * 0.25)
0.25)
R est strictement Oui Chaque nœud interne possède exactement deux fils
binaire
R est complet Non Les feuilles ne se trouvent pas toutes sur le même
niveau

4. Supprimer deux fois la racine de l’arbre R.

Voici les quatre cas possibles


possibles (2 * 0.5)

En choisissant à chaque fois


le prédécesseur

En choisissant à chaque fois


le successeur

1/7
En choisissant le
prédécesseur ensuite le
successeur

En choisissant le successeur
ensuite le prédécesseur

5. Ecrire une fonction récursive qui permet de retourner le nombre des nœuds dans un niveau donnée.
NivC 0 // Niveau Courant, NivA : Niveau à Atteindre)
Fonction NNN (R : ptrN, NivC, NivA : entier) : entier
Si (R = Nil) alors retourner (0)
Sinon Si (NivC = NivA) alors retourner (1)
Sinon retourner (NNN(FG(R), NivC+1, NivA) + NNN(FD(R), NivC+1, NivA))
6. Ecrire une fonction récursive qui permet de vérifier si un arbre binaire est strictement binaire.
Fonction SB (R : ptrN) : booléen
Si (R = Nil) alors retourner (vrai
(vrai)
vrai)
Sinon Si (FG(R)
(FG(R) = FD(R) = Nil)
Nil) alors retourner (vrai
(vrai)
vrai)
Sinon Si ((FG(R) ≠Nil) et (FD(R) ≠Nil)) retourner (SB
(SB(FG(R)
SB(FG(R))
(FG(R)) et SB(FD(R)))
SB(FD(R)))
Sinon retourner (faux)
7. Ecrire une fonction qui permet de vérifier si un arbre binaire est complet. Vous pouvez utiliser
directement la fonction « profondeur(R : ptrN) : entier » qui retourne la profondeur de l’arbre R.
Plusieurs solutions possibles :
Solution itérative Solution récursive
Fonction Complet (R : ptrN) : entier Pf Profondeur (R)
pf Profondeur(R) Fonction Complet (R : ptrN,
ptrN, pf : entier)
entier) : booléen
i 0 Si (R = Nil) alors retourner (vrai)
TQ (i <=
<= pf) faire Sinon Si ((FG(R) = FD(R) = Nil) et (pf = 0)) alors
Si (NNN(R, i) = 2i) alors i++ retourner (vrai)
Sinon retourner (faux) Sinon Si ((FG(R) ≠Nil) et (FD(R) ≠Nil))
FTQ retourner (Complet
(Complet(FG(R)
Complet(FG(R),
(FG(R), pf-
pf-1) et
Retourner (vrai) Complet(FD(R)
Complet(FD(R),
(FD(R), pf-
pf-1))
Sinon retourner (faux)

2/7
Exercice2 (0.5 + 4.5 + 1+ 1 = 7 point):
Une Deque (double ended queue ou une file à
deux bouts) possède à la fois les propriétés d’une
pile et d’une file. Une Deque est définie par deux
extrémités : tête et queue. On peut donc
consulter, ajouter ou supprimer un élément à
chaque extrémité de la structure.
On considère une Deque comme une liste chainée de caractères. Ecrire en LANGAGE C :
1. les structures de données nécessaires pour définir une Deque.
(0.25) typedef struct maillon { (0.25) typedef struct Deque
char val ; {
struct maillon*suiv ; ptrM T;
}maillon; ptrM Q;
typedef maillon* ptrM; } Deque;
2. le modèle de Deque qui contient un ensemble d’opération permettant de la manipuler :
Nom Paramètres Rôle
InitDeque Deque Initialiser une Deque
DequeVide Deque Vérifier si une Deque est vide
Extremite Deque, sens Retourner l’élément qui se trouve soit en tête soit en queue (sans le
supprimer)
EnDequer Deque, x, sens Ajouter l’élément « x » soit en tête soit en queue
DeDequer Deque, x, sens Supprimer un élément soit en tête soit en queue et le retourner dans
«x»
sens est une variable définie pour désigner l’extrémité à utiliser. Elle sera égal à
- 1 si lecture/ajout/suppression en tête
- -1 si lecture/ajout/suppression en queue.

void InitDeque (Deque* D) (0.25) {


{ if (Deque Vide(*F)) { (0.5)
(0.5)
(*D).T = NULL; ptrM P = allouer();
(*D).Q = NULL; aff_val(P, x);
} aff_suiv(P, NULL);
int DequeVide (Deque D) (0.25) (*D).T = P;
{ (*D).Q = P;
return(D.T==D.Q==NULL); }
} else {
char Extremite (Deque D, int sens) (0.5)
(0.5) if (sens == 1) { (0.5)
{ ptrM P = allouer();
if ( !DequeVide(D)) aff_val(P, x);
{ aff_suiv(P, (*D).T);
if (sens == 1) return(valeur
return(valeur (D.T
(D.T)
D.T)); (*D).T = P;
if (sens == -1) return(valeur(
return(valeur(D.Q
valeur(D.Q)
D.Q)); }
} if (sens == -1) { (0.5)
(0.5)
} ptrM P = allouer();
void EnDequer (Deque *D, char x, int sens) aff_val(P, x);

3/7
aff_suiv((*D).Q, P) If (sens == -1) { (1.25)
(1.25)
aff_suiv(P, NULL); ptrM P = (*D).T;
(*D).Q = P; *x = valeur((*D).Q
valeur((*D).Q);
} while (P != (*D).Q) P = suivant (P) ;
} if (P != (*D).T){
} aff_suiv(P, NULL) ;
void Dedequer
Dedequer (Deque *D, char* x, int sens) liberer (&((*D).Q))
{ (*D).Q = P ;
if (!DequeVide(*D)){ } else
if (sens == 1) { (0.75) {
*x = valeur((*D).T); DequeInit(D)
ptrM P=(*D).T; liberer(&P)
(*D).T=suivant((*D).T); }
liberer(&P); }
if ((*D).T == NULL) (*F).Q = NULL; }
} }
3. les opérations suivantes (en utilisant le modèle de Deque):
- Enfiler et défiler dans le cas où Deque est une file FIFO.
- Empiler et dépiler dans le cas où le Deque est une pile LIFO.

Enfiler (D, x) Endequer (D, x, -1) (0.25)


(0.25) Defiler (D, x) Dedequer (D, x, 1) (0.25)
(0.25)
Empiler (D.T, x) Endequer (D, x, 1) (0.25)
(0.25) Depiler (D.T, x) Dedequer (D, x, 1) (0.25)
(0.25)

4. une fonction récursive qui permet de vérifier si le mot contenu dans une Deque est un palindrome (en
utilisant le modèle de Deque). Rappeler qu’un palindrome est un mot qui se lit de la même manière de
gauche à droite et de droite à gauche comme « radar », « été », « ressasser », « selles »…..
int palindrome (Deque D)

if (DequeVide(D)) return 1 ; (0.25)

else {

if (Extremite(D, 1) != Extremite(D, -1))


1)) return (0); (0.25)

else { (0.5)

Dedequer (D, x, 1);


1);

Dedequer (D, x, -1);


1);

return (Palindrome (D));

} }

4/7
Exercice3 (0.5 + 2.5 = 3 points)
Un polynôme peut être représenté par une LLC triée dans l’ordre décroissant des puissances où chaque
maillon contient un monôme qui est représenté par un exposant et un coefficient (non nul). Par
exemple, le polynôme P(x) = 2x5+3x4 + 0.5x2 + 1 est représenté par la liste suivante :
type monome = structure type maillon = structure
coef :réel val : monome
puiss : entier positif suiv : * maillon
Fin Fin
type ptrM = * maillon

En utilisant le modèle de LLC, écrire les fonctions suivantes :


1. PValeur (P, x) qui calcule le polynôme P en un point x donné.
Fonction PValeur (P : ptrM, x : reel) : reel
S 0
TQ (P ≠ nil) faire S S + valeur(P).coef*Puiss(x, valeur(P).puis) FTQ
Retourner (S)

2. Soustraction (P, Q) qui retourne le résultat de la soustraction de deux polynômes P et Q (P-Q). Par
exemple, si P(x) = 2x5+3x4 + 0.5x2 +1 et Q(x) = 2x4 + 0.5x2 + 3x - 5 alors P-Q = 2x5+x4 -3 x +4

Fonction Soustraction (P, Q : ptrM)


ptrM) : ptrM V valeur(P)
T Nil ; F Nil P suivant(P)
TQ (P ≠ nil) et (Q ≠ nil) faire InsererFin(T, F, v)
Si (valeur (P).puis = valeur(Q).puis) alors FTQ
v.puiss valeur(P).puiss TQ (Q ≠ nil) faire
v.coef valeur(P).coef – V valeur(Q)
valeur(Q).coef Q suivant(Q)
P suivant(P) InsererFin(T, F, v)
Q suivant(Q) FTQ
Sinon Si (valeur (P).puis > Procédure InsererFin (Var T, F : ptrM, v :
valeur(Q).puis) alors monome)
V valeur(P) S allouer()
P suivant(P) Aff_val(S, v)
Sinon Aff_suiv(S, Nil)
V valeur(Q) Si (T = Nil) alors T S
Q suivant(Q) Sinon aff_suiv(F, S)
Si v.coef ≠ 0 alors InsererFin(T, F, v) F S
FTQ Fin
TQ (P ≠ nil) faire

Exercice4
Exercice4 (1 + 1.25
1.25 + 1.75 = 4 points) :
Soit « IND » un index des mots qui est défini par un tableau « Tab » de taille n où chaque case du tableau
« Tab » contient un entier qui représente la longueur du mot et un pointeur vers une liste linéaire
chaînée unidirectionnelle. Cette liste contient des mots de même longueurs à raison d’un mot par
maillon. Le tableau est trié selon l’ordre décroissant de la longueur du mot. Les listes sont triées par
ordre alphabétique (ordre croissant de A à Z).
5/7
type maillon = structure Const Max = 100 ;
val : chaîne de caractères type index = structure
suiv : * maillon Tab: Tableau [Max] de case
Fin Queue :entier
type ptrM = * maillon Fin
type case = structure
long : entier
tête :ptrM
Fin

Dans le but d’insérer un mot dans cet index, il est demandé d’écrire les modules suivants:
1. La fonction récursive « RechSeqTab » qui permet de retourner l’indice de la case contenant une
longueur donnée (soit x) si elle existe, sinon l’indice de la case devant contenir la longueur « x ».
Fonction RechSeqTab(Tab : Tableau [] de case, x, n: entier)
Si n = 0 alors retourner (n
(n) (0.25)
(0.25)
Sinon
Si Tab[n-
Tab[n-1].long = x alors retourner (n-
(n-1) (0.25)
(0.25)
Sinon
Si Tab[n-
Tab[n-1].long < x alors retourner (RechSeqTab (Tab, x, n-
n-1)) (0.25)
(0.25)
Sinon retourner (n
(n) (0.25)
(0.25)
Fin
Ou bien
Fonction RechSeqTab(Tab : Tableau [] de case, i,x,n : entier)
Si i = n alors retourner (i
(i) (0.25)
(0.25)
Sinon
Si Tab[i].long = x alors retourner (i) (0.25)
(0.25)
Sinon
Si Tab[i].long > x alors retourner (RechSeqTab (Tab, i+1, x, n)) (0.25)
(0.25)
Sinon retourner (i
(i) (0.25)
(0.25)
Fin

2. La fonction récursive « InsLLC » qui permet d’insérer dans une liste linéaire chaînée ordonnée un
nouveau mot (i.e le mot ne doit pas exister déjà).

Fonction InsLLC(L : ptrM,


ptrM, y : chaine de caractère) : ptrM
Si (L = Nil) ou cmpch
cmpch(valeur(L),
ch(valeur(L), y)>0) alors (0.5)
(0.5)
P allouer()
Aff_val(P, y)
Aff_suiv(P, Nil)

6/7
Retourner (P)
Sinon Si (cmpch
(cmpch(valeur(L),
ch(valeur(L), y)<0)) alors (0.5)
(0.5)
aff_suiv(L, InsLLC(suivant(L), y))
retourner (L)
sinon retourner
retourner (L) (0.25)
(0.25)
Fin

3. En utilisant les fonctions précédentes, écrire la procédure « Insérer (var ID : index, y :chaine de
caractère) » qui permet d’insérer un nouveau mot « y » dans l’index « ID ». S’il n’existe pas déjà des
mots de même longueur que « y », une nouvelle case est insérée dans le tableau Tab.
INDICATION.
INDICATION Vous pouvez utiliser les fonctions suivantes :
a. Longch(ch : chaine de caractère) : entier qui retourne le nombre de caractère dans ch.
b. Cmpch (ch1, ch2 : chaine de caractère) : entier qui compare les chaînes ch1 et ch2 et retourne une valeur
négative si (lexicalement) ch1 < ch2, nulle si ch1 = ch2 et positive si ch1 > ch2.
procédure Insérer (var ID : index, y :chaine de caractère)
1 (0.25)
(0.25):
5): i RechSeqTab(ID.Tab,Longch(y), ID.Queue+1) // ou bien RechSeqTab(ID.Tab, 0,Longch(y),
ID.Queue+1)
2 (0.25)
(0.25):
5): Si (i <=ID.Queue) et (longch(y)
(longch(y) = ID.Tab[i].long)
ID.Tab[i].long) alors // s’il existe déjà des mots de même
longueur que y
//insérer dans la liste
3 : (0.25)ID.Tab[i].Tete
(0.25)ID.Tab[i].Tete InsLLC(ID.Tab(i].Tete, y)
Sinon // y est le premier mot de la liste
4 : (0.2
(0.25) Pour j ID.Queue à i pas -1 faire //décalage à droite
ID.Tab[j+1] ID.Tab[j]
//insérer une nouvelle case dans le tableau
5 : (0.25) ID.Tab[i].long longch(y)
6: (0.25)
(0.25) ID.Tab[i].Tete InsLLC(Nil, y)
7: (0.25)
(0.25) ID.queue ++

7/7

Vous aimerez peut-être aussi