You are on page 1of 9

DUT Informatique Conception de structures de donnees Annee 2009/2010

- EXAMEN - sujet A -
- Aucun document autorise - Calculatrices interdites - Duree : 2 heures -
NOM :
Prenom :
3 pts Exercice 1. Cellules en cycle
En utilisant le type Cell deni pour les listes, on declare le pointeur p1 comme suit :
Cell *p1=createCell(1,createCell(2,createCell(3,NULL))) ;
(((p1->next)->next)->next)=p1 ;
Remarque : dans la deuxi`eme instruction, les `eches sont superues.
1. Le resultat des 2 instructions precedentes provoque un cycle dans le chanage des cellules,
qui se traduit graphiquement ainsi :
2 1 3
p1
Representez sur le dessin ci-dessous les pointeurs (`eches) permettant dinverser les posi-
tions des cellules contenant 2 et 3, de telle sorte que les trois cellules forment toujours un
cycle. Numerotez-les suivant lordre dans lequel ils doivent etre aectes pour que lechange
fonctionne. Vous navez pas le droit dajouter de nouveaux pointeurs.
2 1 3
p1
2.

Ecrivez le code C correspondant, cest-`a-dire les instructions permettant dinverser les po-
sitions des cellules contenant 2 et 3 (en conservant le cycle) sans declarer de nouveaux
pointeurs ni modier les champs elem des cellules.
1
4 pts Exercice 2. Tables de Hachage
Voici une liste de titres de lms accompagnes de leur
date de sortie au cinema. Dans cet exercice, vous ma-
nipulerez des tables de hachage permettant de stocker
ces informations. Les titres sont les cles et les donnees
sont les annees de sortie des lms. Dans tous les cas, la
fonction de hachage h est le nombre de caract`eres du
titre (espaces compris) modulo la longueur de la table.
Par exemple h(Psychose) vaut 8 pour une table de
longueur 10, mais seulement 3 pour une table de lon-
gueur 5.
Le Parrain (1972)
Apocalypse Now (1979)
Pulp Fiction (1994)
Fight Club (1999)
Raging Bull (1980)
Taxi Driver (1976)
Casablanca (1942)
Le Parrain II (1974)
Blade Runner (1982)
Citizen Kane (1941)
Die Hard (1988)
Terminator 2 (1991)
Orange Mcanique (1971)
Psychose (1960)
E.T. (1982)
1. Quest-ce quune collision dans une table de hachage ?
2. Representer (verticalement) une table de hachage de longueur 10 contenant les lms et leur
date de sortie inseres dans lordre donne ci-dessus. Les collisions sont resolues par chanage.
Une association peut etre representee comme un couple (film,date).
2
3. Representer (verticalement) une table de hachage de longueur 20 contenant les lms et leur
date de sortie inseres dans lordre donne ci-dessus. Les collisions sont resolues par adressage
ouvert en utilisant un sondage lineaire.
Que se passe-t-il si la table est de longueur 10 ?
4. Dans le cas du sondage lineaire, quelle est la complexite de la suppression dun element dans
une table de hachage de longueur n (les operations que lon compte sont les comparaisons
entre cles) ? Justiez votre reponse.
3
5 pts Exercice 3. Listes de chanes de caract`eres
Dans cet exercice, on consid`ere que le type Element correspond `a char * an de pouvoir
manipuler des listes de chanes de caract`eres (voir exemple en n dexercice).
1. Est-ce que lon peut tester legalite de 2 chanes de caract`eres en utilisant ==? Expliquez
pourquoi.
2. La fonction que vous devez ecrire prend en param`etre une chaine de caract`eres (terminee
par un \0) constituee de mots (de longueur 20, au maximum) separes par un caract`ere .
Le caract`ere precedant le \0 est aussi un espace.

Ecrivez la fonction stringToList qui, etant donnee une telle chane, renvoie une liste conte-
nant tous les mots de la chane (dans nimporte quel ordre). Faites attention `a lallocation
de la memoire. Vous navez pas besoin de verier que la chane est bien formee.
List stringToList(char *s)
4
3.

Ecrivez la fonction recursive nbVwords qui, etant donnee une liste de mots (obtenue avec
la fonction precedente, par exemple), renvoie le nombre de mots de la liste qui commencent
par une voyelle (a,e,i,o,u,y).
int nbVwords(List l)
4.

Ecrivez la fonction recursive beforeWord qui, etant donnee une liste de mots l et un
mot s, renvoie une liste contenant tous les mots de l qui se trouvent avant s dans lordre
alphabetique. Il nest pas necessaire de fabriquer des copies des mots.
List beforeWord(List l, char *s)
Exemple dutilisation des fonctions de cet exercice :
List ls = stringToList("albatros chat pigeon iguane ornithorynque chien biche
corbeau otarie chameau souris cerf ");
printList(ls);
printf("\n nombre de mots commencant par une voyelle: %d\n",nbVwords(ls));
List beforeChasseur = beforeWord(ls,"chasseur");
printf("\n liste des mots avant chasseur dans la liste ls: ");
printList(beforeChasseur);
resultat :
[ cerf souris chameau otarie corbeau biche chien ornithorynque iguane pigeon chat albatros ]
nombre de mots commencant par une voyelle : 4
liste des mots avant chasseur dans la liste ls : [ cerf chameau biche albatros ]
5
10 pts Exercice 4. Expressions arithmetiques
Dans cet exercice, on sinteresse aux expressions arithmetiques enti`eres contenant des additions,
des soustractions et des multiplications binaires (2 operandes). Nous allons utiliser dierentes
structures de donnees pour les representer et les calculer.
Pour coder ces expressions arithmetiques, on utilise des entiers pour les valeurs numeriques et
les caract`eres +, - et * pour les operateurs binaires correspondants.
1. Commencez par ecrire la fonction calculer qui calcule le resultat de loperation a opb si
op est bien un des trois operateurs binaires possibles et renvoie une erreur sinon.
int calculer(char op, int a, int b)
Toute expression arithmetique compl`etement parenthesee peut secrire sous la forme dun arbre
binaire dont les elements sont soit des operateurs, soit des entiers.
Plus precisement, larbre associe `a une expression arithmetique e est deni recursivement ainsi :
si e est un nombre, alors larbre associe est une feuille dont la racine est e.
sinon, e est de la forme (e
1
) op (e
2
) o` u op est un operateur binaire et e
1
et e
2
sont des
expressions arithmetiques ; larbre associe est un arbre binaire dont la racine est op et ses
deux ls sont les arbres binaires associes `a e
1
et e
2
.
Voici quelques exemples :
+
* *
5 - +
10
1
4
3 1
-
8 -
4 2
5
e1 = 5
e3 = ((10-3)*(1+1))+(4*5) = 34
e2 = 8-(4-2) = 6
attention: e = 8-4-2
le1 = [ 5 ]
le2 = [ '-' 8 '-' 4 2 ]
le3 = [ '+' '*' '-' 10 3 '+' 1 1 '*' 4 5 ]
Une expression arithmetique peut egalement etre representee de fa con unique par la liste des
elements de larbre en ordre prexe (voir le1, le2 et le3 dans lexemple ci-dessus).
! Pour toutes les complexites demandees dans cet exercice, les operations elemen-
taires sont les aectations de pointeurs (deplacements dans les listes ou les arbres).
6
2. Les arbres representant les expressions arithmetiques sont-ils des arbres complets (justier) ?
Quels types delements se retrouvent dans les feuilles ? Et dans les noeuds internes (ceux
qui ne sont pas des feuilles) ?
3. Pour coder les arbres et les listes associes aux expressions arithmetiques en C, on denit le
type des elements an quils puissent etre aussi bien des nombres que des operateurs :
typedef struct{ int val ; char op ; }Element ;
On vous fournit egalement 2 fonctions permettant de fabriquer des elements :
Element makeOp(char c){ Element res ; res.op=c ; return res ; }
Element makeVal(int v){ return (Element){v,n} ; }
Ecrivez les deux fonctions suivantes qui testent respectivement si e est un operateur ou une
valeur :
int isOp(Element e)
int isVal(Element e)
4.

Ecrivez la fonction debutCerise, qui etant donnee une liste de nombres et doperateurs
(de type Element), renvoie 1 si les trois premi`eres cellules de la liste forment une cerise,
cest-`a-dire que le premier element est un operateur et les deux suivants sont des nombres.
Si ce nest pas le cas, la fonction renvoie 0.
Par exemple, debutCerise(le3)=0 et debutCerise(queue(queue(le3)))=1.
7
int debutCerise(List l)
5.

Ecrivez la fonction trouverCerise, qui etant donnee une liste, renvoie un pointeur sur la
premi`ere cerise de la liste ou NULL sil ny en a pas.
Par exemple, trouverCerise(le3) renvoie un pointeur sur la cellule contenant le char -.
Cell *trouverCerise(List l)
6.

Ecrivez la fonction reduireCerise, qui remplace les 3 cellules dune cerise [op a b] dans
une liste par la valeur de lexpression arithmetique a opb. Le param`etre c est une pointeur
sur la premi`ere cellule de la cerise. Le reste de la liste ne doit pas etre modie.
(Indice : vous netes pas oblige de creer une nouvelle cellule.)
Par exemple, si on ache le3 apr`es linstruction reduireCerise(queue(queue(le3))), on
obtient le3 = [ + * 7 + 1 1 * 4 5 ].
void reduireCerise(Cell *c)
8
7. Que fait la fonction suivante (bt est un arbre dexpression arithmetique non vide) ?
int mystere(BTree bt){
List l=listPrefixOrder(bt); /* la liste des elements de bt en ordre prefixe */
while(!isEmpty(queue(l))){
Cell *c=trouverCerise(l);
if(c==NULL) erreur("liste mal formee");
reduireCerise(c);
}
return elemVal(first(l));
}
8. Quelle est la complexite de mystere en fonction de la taille n de larbre (justier) ?
9. Ecrivez la fonction recursive calculerExp qui calcule directement la valeur de lexpression
arithmetique representee par larbre bt (sans passer par la liste en ordre prexe !). On
suppose que bt est un arbre bien forme (qui correspond `a une expression arithmetique).
int calculerExp(BTree bt)
10. Quelle est la complexite de calculerExp en fonction de la taille n de larbre (justier) ? En
comparant avec la question 8, quen deduisez-vous ?
9

You might also like