1 /******************************************************************************/
2 /* examen algo II avec implantation */
3 /* des expressions arithmetiques */
4 /******************************************************************************/
7 /* Exercice 1 : questions de cours (correction rapide)
9 1) Utilisation d'une fonction de hachage sur une valeur pour calculer la cle qui est alors utilisee pour ranger la valeur dans un tableau a l'indice cle.
10 La recherche d'une valeur est alors immediate : calcul de la cle puis acces a l'element d'indice cle dans le tableau.
12 2) Dans le pire des cas, AVL car O(log n) pour recherche, insertion et suppression.
13 Et aussi, tableau (trie) avec methode dichotomique, mais O(log n) pour la recherche seulement.
15 3) En moyenne, Hachage car O(1) pour recherche, insertion et suppression.
18 Par l'absurde, si l'element de plus petite priorite n'est pas dans une feuille alors cela signifie qu'il existe un noeud fils de plus grande priorite. Contradiction avec la definition d'un tas (tout noeud est >= a chacun de ses fils).
22 /* Exercice 2 : expressions arithmetiques*/
24 /* remarques : pour l'examen, algorithmes en pseudo-code,
25 avec des libertes possibles comme dire "la valeur est un operateur".
26 Bien entendu, il y a plusieurs facon de rediger un algo.
38 typedef struct noeud
{
45 /* Creation d'un arbre vide */
52 /* Affichage du contenu de l'arbre (parcours infixe) */
53 void affiche(NOEUD
* p
)
56 if (p
->gauche
!= NULL
)
57 printf("( "); /* p est une feuille (si gauche null alors droit aussi) */
59 printf("%c ", p
->valeur
);
62 printf(") "); /* p est une feuille (si droit null alors gauche aussi) */
67 /* Test si un arbre est bien une EA valide */
68 int est_valide(NOEUD
* p
)
72 else if (p
->valeur
== '+' || p
->valeur
== '-' || p
->valeur
== '*'
74 return (est_valide(p
->gauche
) && est_valide(p
->droit
));
76 return (p
->gauche
== NULL
&& p
->droit
== NULL
);
80 /* Test si deux arbres sont egaux (identiques) */
81 int egal(NOEUD
* A1
, NOEUD
* A2
)
83 if (A1
== NULL
|| A2
== NULL
)
84 return (A1
== NULL
&& A2
== NULL
);
86 return ((A1
->valeur
== A2
->valeur
)
87 && egal(A1
->gauche
, A2
->gauche
)
88 && egal(A1
->droit
, A2
->droit
));
92 /* Evaluation d'une EA (un arbre) */
96 return eval(p
->gauche
) + eval(p
->droit
);
97 else if (p
->valeur
== '-')
98 return eval(p
->gauche
) - eval(p
->droit
);
99 else if (p
->valeur
== '*')
100 return eval(p
->gauche
) * eval(p
->droit
);
101 else if (p
->valeur
== '/')
102 return eval(p
->gauche
) / eval(p
->droit
);
104 return atoi(&p
->valeur
); /* convertion du char en int */
108 /* Construction de l'arbre correspondant a une EA lue au clavier */
109 NOEUD
*construit(char courant
)
113 /* printf("traitement de %c\n",courant); */
115 if (courant
!= '(' && courant
!= ')' && courant
!= '+'
116 && courant
!= '-' && courant
!= '*' && courant
!= '/') {
117 p
= (NOEUD
*) malloc(sizeof(NOEUD
));
121 } else { /* courant est '(' */
122 /* l'EA est de la forme (E1 operateur E2) */
126 scanf("%c", &courant2
);
128 p
= (NOEUD
*) malloc(sizeof(NOEUD
));
129 /* traitement de E1 */
130 p
->gauche
= construit(courant2
);
132 /* lecture de l'operateur */
134 scanf("%c", &courant3
);
136 p
->valeur
= courant3
;
140 scanf("%c", &courant4
);
142 /* traitement de E2 */
143 p
->droit
= construit(courant4
);
147 scanf("%c", &courant5
);
157 /* Affichage de l'arbre (sous forme arborescente) */
158 void affiche_arbre(NOEUD
* p
, int col
)
162 affiche_arbre(p
->droit
, col
+ 1);
163 for (i
= 0; i
< col
; i
++)
165 printf("%c\n", p
->valeur
);
166 affiche_arbre(p
->gauche
, col
+ 1);
171 /* Destruction de l'arbre de racine p en recuperant la place occupee (free) par chacun des noeuds */
172 NOEUD
*detruis_arbre(NOEUD
* p
)
177 p
->gauche
= detruis_arbre(p
->gauche
);
178 p
->droit
= detruis_arbre(p
->droit
);
186 /* Creation d'un noeud */
187 NOEUD
*cree_noeud(char valeur
, NOEUD
* filsgauche
, NOEUD
* filsdroit
)
189 NOEUD
*p
= (NOEUD
*) malloc(sizeof(NOEUD
));
191 p
->gauche
= filsgauche
;
192 p
->droit
= filsdroit
;
197 /****************************************************************************/
200 NOEUD
*ea
= arbre_vide();
202 /* creation "a la main" de (9 + (3 * 2)) */
203 NOEUD
*feuille9
= cree_noeud('9', NULL
, NULL
);
204 NOEUD
*feuille3
= cree_noeud('3', NULL
, NULL
);
205 NOEUD
*feuille2
= cree_noeud('2', NULL
, NULL
);
206 NOEUD
*ea2
= cree_noeud('*', feuille3
, feuille2
);
207 ea
= cree_noeud('+', feuille9
, ea2
);
209 printf("expression arithmetique : \n");
212 affiche_arbre(ea
, 0);
214 int valide
= est_valide(ea
);
216 printf("l'expression est valide\n");
218 printf("l'expression n'est pas valide\n");
220 int resultat
= eval(ea
);
221 printf("resultat = %d\n", resultat
);
225 NOEUD
*eab
= arbre_vide();
226 NOEUD
*feuille9b
= cree_noeud('9', NULL
, NULL
);
227 NOEUD
*feuille3b
= cree_noeud('3', NULL
, NULL
);
228 NOEUD
*feuille2b
= cree_noeud('2', NULL
, NULL
);
229 NOEUD
*ea2b
= cree_noeud('*', feuille3b
, feuille2b
);
230 eab
= cree_noeud('+', feuille9b
, ea2b
);
231 printf("\nexpression arithmetique 2 : \n");
235 int egalite
= egal(ea
, eab
);
237 printf("les 2 expressions sont identiques\n");
239 printf("les 2 expressions ne sont pas identiques\n");
242 /* test construction */
244 ("\nsaisir une expression arithmetique (un caractere a la fois) : \n");
246 scanf("%c", &courant
);
247 getchar(); /* lecture de '(' */
248 ea
= construit(courant
);
250 printf("expression arithmetique : \n");
253 affiche_arbre(ea
, 0);
254 printf("resultat = %d\n", eval(ea
));
257 /***** exemple d'execution ********************************************
258 expression arithmetique :
265 l'expression est valide
268 expression arithmetique 2 :
270 les 2 expressions sont identiques
272 saisir une expression arithmetique (un caractere a la fois) :
282 expression arithmetique :
290 *******************************************************************/