Arbres binaires en représentation chaînée Construction Libération Opérations diverses 17/01/06 Bac2 - JMD - ArbrBin.ppt 1
Arbre n-aire Arbre binaire a b c d e f arbre n-aire e b a c f d arbre binaire 17/01/06 Bac2 - JMD - ArbrBin.ppt 2
Exemples d'utilisation des arbres Modélisation de l'espace d'états d'un problème de planification (figure 1). Modélisation du raisonnement d'un système expert à règles (figure 2). Modélisation d'un processus de diagnostic (figure 3) Structuration de l'analyse sémantique d'une expression sur son arbre syntaxique (figure 4) Mémorisation en mémoire d'un dictionnaire (figure 5). Représentation de la structure d'une phrase pour la traduire, pour la prononcer (intonation), la comprendre. Autres : Arbre généalogique (arbre de descendance), représentation du déroulement d'un tournoi de tennis, représentation de la structure d'un cours (chapitres, paragraphes, etc.), représentation d'une interface graphique avec fenêtres et sous fenêtre (fenêtre cadre, menus,barre d'outils, barre d'état, vues diverses, etc.), nomenclature d'un ensemble, représentation d'une classification (espèces animales), arbre de décision, etc. 17/01/06 Bac2 - JMD - ArbrBin.ppt 3
A B C ((A)(B)C)) A B A C B A B C C A C B A B C A C B B A C B C A C A B C B A ((BA)C) ((CA)B) ((AB)C) ((CB)A) ((AC)B) ((BC)A) C B B A C B A B B C A C C A B B A C C B A A B C B C A A C B ((BAC)) ((CAB )) ((ABC)) ((CB)A) ((ACB)) ((BCA)) Action : X Y (déplacer X sur Y) Contraintes : pas de retour sur un état déjà atteint et pas de déplacement d'un cube qui est sous un autre ESPACE D'ETATS Univers de cubes Problème de planification (trouver une suite d'actions pour un résultat sous contraintes) Figure 1
OK OK OK règle 5 règle 1 et et SOLDE REPUTATION GARANT MOYENS REPUTATION REPUTATION GARANT MOYENS REPUTATION règle 3 règle 2 règle 4 règle 3 BON_PAYEUR GARANTIES REVENUS BON_PAYEUR LES FAITS : OK : SOLDE : REPUTATION : BONPAYEUR : GARANT : GARANTIES : MOYENS : REVENUS : le prêt est accordé en moyenne, le solde du compte de l'emprunteur est positif l'emprunteur a une bonne réputation financière l'emprunteur n'est pas "fiché" le garant du prêt est satisfaisant les garanties apportées par le garant sont suffisamment importantes par rapport au prêt l'emprunteur a les moyens de payer l'emprunteur a des revenus supérieurs à ses dépenses LES REGLES : REGLE 1 : SI GARANT et MOYENS et REPUTATION ALORS OK REGLE 2 : SI GARANTIES ALORS GARANT REGLE 3 : SI BON_PAYEUR ALORS REPUTATION REGLE 4 : SI REVENUS ALORS MOYENS REGLE 5 : SI SOLDE et REPUTATION ALORS OK FONCTIONNEMENT D'UN SYSTEME EXPERT à règles pour l'octroi de prêts : arbre de recherche de preuve Démonstration dans le cadre d'un fonctionnement en chaînage arrière Figure 2
Démarre? non Démarreur tourne? non oui Lampes s'éteignent? Moteur "tousse"? oui non oui non Batterie défectueuse? Démarreur défectueux Moteur noyé Réservoir vide? oui Batterie déchargée non Bornes oxidées non Allumage défectueux Diagnostic au démarrage d'une voiture Figure 3
<Id> <Expr> (14) 1 ( ) <Op> (7) 1 + <Id> <Expr> (8) 4 4 (10) <Expr1> <Expr> 3 4 3 (14) (7) (12) 3 3 4 (3) 4 1+ (8) (9) <Expr1> (12) <Expr1> 4 (2) 4 (12) <Expr1> <Expr> ::= ( <Expr> ) <Expr1> - <Expr> <Expr1> <Id> <Expr1> <Expr1> ::= <Op> <Expr> <Expr1> ε <Op> ::= + - * / ^ <Id> ::= 0.. 9 ( 1 + 3 ε ε ) ε Structuration de l'analyse sémantique d'une expression selon son arbre syntaxique ( flux de données lors de l'évaluation de l'expression ) Figure 4
Syntaxe Sémantique <E>::= ( <E'> ) <E1> - <E'> <E1> <Id> <E1> E'.signin = 1 (1) E1.vin = E'.vout (2) E.vout = E.signin * E1.vout (3) E'.signin = -1 (4) E1.vin = E'.vout (5) E.vout = E.signin * E1.vout (6) E1.vin = E.signin * Id.vout (7) E.vout = E1.vout (8) <E1>::=<Op> <E> <E1'> ε E1'.vin = E1.vin <Op> E.vout (9) E1.vout = E1'.vout (10) E.signin = 1 (11) E1.vout = E1.vin (12) <Op> ::= + - * / ^ <Id> ::= 0.. 9 etc. (13) Id.vout = 0.. 9 (14)
m a* e* o s a o e* i* r r n n l s s Collection de mots ou dictionnaire (mode de saisie T9 sur GSM) Les début communs ne sont mémorisés qu'une seule fois...... mais, mai, ma, mars, mer, me, mon,... sa, son, sel, se,... Figure 5
Arbre binaire Expression parenthésée abg valeur ab abd <arbre_binaire> ::= ( <valeur>,<arbre_binaire>,<arbre_binaire>) ( ) 17/01/06 Bac2 - JMD - ArbrBin.ppt 10
Arbre binaire () arbre binaire vide + + 2.5 1.0 2.0 (+,(+(1.0,(),()),(2.0,(),()),(2.5,(),())) arbre binaire quelconque complet 17/01/06 Bac2 - JMD - ArbrBin.ppt 11
Arbre binaire a b c d e f (a,(b,(d,(),()),(e,(),())),(c,(),(f,(),()))) arbre binaire quelconque incomplet 17/01/06 Bac2 - JMD - ArbrBin.ppt 12
Représentation chaînée d'un arbre binaire X () arbre vide + arbre quelconque 1.0 X X + 2.5 X X 2.0 X X noeud (+,(+(1.0,(),()),(2.0,(),()),(2.5,(),())) 17/01/06 Bac2 - JMD - ArbrBin.ppt 13
Déclaration d'un noeud typedef struct NOEUD { char val[maxsymb+1]; struct NOEUD* sag; struct NOEUD* sad; } NOEUD; 17/01/06 Bac2 - JMD - ArbrBin.ppt 14
Construction traduction d'une expression parenthésée /*------------------------------------------------------------------------------ Traduit une expression, préfix de la chaîne de caractères <*pe> en l'arbre <*pa> correspondant. Si la traduction échoue retourne 0 sinon 1. La syntaxe reconnue est : <arbre> := () (<symbole>,<arbre>,<arbre>) ------------------------------------------------------------------------------*/ int ConstruireArbre0(char** pe,noeud** pa) ; 17/01/06 Bac2 - JMD - ArbrBin.ppt 15
Construction traduction d'une expression parenthésée int ConstruireArbre0(char** pe,noeud** pa) { char s[maxsymb+1]; NOEUD *ag,*ad; *pa=null;ag=null;ad=null; if (*(*pe)++=='(') if (**pe==')') { *pa=null; (*pe)++; return 1; } else if (Symb0(pe,s)) if (*(*pe)++==',') if (ConstruireArbre0(pe,&ag)) if (*(*pe)++==',') if (ConstruireArbre0(pe,&ad)) if (*(*pe)++==')') if ((*pa=malloc(sizeof(noeud)))!=null) { strcpy((*pa)->val,s); (*pa)->sag=ag; (*pa)->sad=ad; return 1; } LibererArbre(&ag);LibererArbre(&ad);return 0; } /* ConstruireArbre0 */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 16
Construction traduction d'une expression parenthésée /* Retourne 1 si le caractère <c> est admissible. Sinon retourne 0. La syntaxe reconnue est : <caradmis> ::= <alphabétique> <chiffre> + - * /. (point) */ static int CarAdmis(char c) { if (c=='\0') return 0; return (isalpha(c) isdigit(c) strchr("+-*/.",c)); } /* CarAdmis */ /* Traduit un symbole, prefix de la chaîne de caractères <*pe> en une chaîne <s> Si la traduction échoue retourne 0 sinon!=0. La syntaxe reconnue est : <symbole> ::= <caradmis> <symbole> empty */ static int Symb0(char** pe, char* s) { int i; for (i=0;(i<maxsymb && CarAdmis(**pe));i++) *s++ = *(*pe)++; *s='\0'; return 1; } /* Symb0 */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 17
Construction traduction à la volée d'une expression parenthésée /*------------------------------------------------------------------------------ Traduit à la volée (au fur et à mesure de la saisie) une expression parenthésée entrée au clavier en l'arbre binaire correspondant <*pa>. La traduction n'échoue que sur une allocation impossible. NB Pas de correction possible si entrée syntaxiquement correcte. La syntaxe reconnue est : <arbre> := ( ) (<symbole>,<arbre>,<arbre>) ------------------------------------------------------------------------------*/ int ConstruireArbre1(NOEUD** pa) ; 17/01/06 Bac2 - JMD - ArbrBin.ppt 18
Construction traduction à la volée d'une expression parenthésée int ConstruireArbre1(NOEUD** pa) { char s[maxsymb+1]; char c; NOEUD *ag,*ad; *pa=null;ag=null;ad=null; while ((c=getch())!='('); putch(c); if ((c=getch())==')') { putch(c); *pa=null; return 1; } else{ ungetch(c); Symb1(s); while ((c=getch())!=','); putch(c); if (ConstruireArbre1(&ag)) { while ((c=getch())!=','); putch(c); if (ConstruireArbre1(&ad)) { while ((c=getch())!=')'); putch(c); if ((*pa=malloc(sizeof(noeud)))!=null) { strcpy((*pa)->val,s); (*pa)->sag=ag; (*pa)->sad=ad; return 1; }/* if ((*pa=malloc(...*/ }/*if (ConstruireArbre1(&ad))*/ }/*if (ConstruireArbre1(&ag))*/ } /* else */ LibererArbre(&ag); LibererArbre(&ad); return 0; } /* ConstruireArbre1 */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 19
Construction traduction à la volée d'une expression parenthésée /* Traduit à la volée (au fur et à mesure de la saisie) un symbole admissible en une chaîne <s>. La traduction réussit toujours. La syntaxe reconnue est : <symbole> ::= <caradmis> <symbole> empty */ static void Symb1(char* s) { int i; char c; i=0; while (((c=getch())!=',') && i<maxsymb) { /* et pas i<maxsymb && ((c=getch())!=',') */ if (CarAdmis(c)) { putch(c); *(s+i)=c; i++; } } /* while */ *(s+i)='\0'; ungetch(c); return; } /* Symb1 */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 20
Construction traduction à la volée d'une expression parenthésée /* Retourne 1 si le caractère <c> est admissible. Sinon retourne 0. La syntaxe reconnue est : <caradmis> ::= <alphabétique> <chiffre> + - * /. (point) */ static int CarAdmis(char c) { if (c=='\0') return 0; return (isalpha(c) isdigit(c) strchr("+-*/.",c)); } /* CarAdmis */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 21
Affichage void AfficherArbre(NOEUD* a) { AfficherArbre1(a); printf("\n"); } /* AfficherArbre */ static void AfficherArbre1(NOEUD* a) { if (a==null) printf("()"); else{ printf("(%s,",a->val); AfficherArbre1(a->sag); printf(","); AfficherArbre1(a->sad); printf(")"); } } /* AfficherArbre1 */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 22
Libération void LibererArbre(NOEUD* *a) { if (*a!=null) { LibererArbre(&((*a)->sag)); LibererArbre(&((*a)->sad)); free(*a); *a=null; } }/* LibererArbre */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 23
Profondeur 0 a 1 a b c d e 3 Le nombre de n uds sur le plus long chemin. 17/01/06 Bac2 - JMD - ArbrBin.ppt 24
Profondeur int Profondeur(NOEUD* a) { int pg,pd; if (a==null) return 0; else{ pg=profondeur(a->sag); pd=profondeur(a->sad); if (pg>pd) return pg+1; else return pd+1; } } /* Profondeur */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 25
Copie int Copier(NOEUD* a1, NOEUD** a2) { if (a1==null) { *a2=null; return 1; } if (*a2=malloc(sizeof(noeud))) { strcpy((*a2)->val,a1->val); if (Copier(a1->sag,&((*a2)->sag))) if (Copier(a1->sad,&((*a2)->sad))) return 1; else LibererArbre(&(*a2)->sag); else { free(*a2);*a2=null;} } return 0; } /* Copier */ Copie dans un miroir? 17/01/06 Bac2 - JMD - ArbrBin.ppt 26
Egalité Appartenance int Egal(NOEUD* a1,noeud* a2) { if (a1==null && a2==null) return 1; else if (a1==null) return 0; else if (a2==null) return 0; else if (strcmp(a1->val,a2->val)==0) return ( Egal(a1->sag,a2->sag) && Egal(a1->sad,a2->sad) ); else return 0; } /* Egal */ int AppartientA(char* x, NOEUD* a) { if (a==null) return 0; else if (strcmp(x,a->val)==0) return 1; else return ( AppartientA(x,a->sag) AppartientA(x,a->sad) ); } /* AppartientA */ 17/01/06 Bac2 - JMD - ArbrBin.ppt 27
Test du module "ArbrBin" #include "ArbrBin.h" #include "Lecture.h" #include <malloc.h> #include <stdio.h> #include <crtdbg.h> int main() { NOEUD * arbr1, *arbr2; char * expr, *memexpr; if (ObtenirArbre(&arbr1)) { printf("arbre : "); AfficherArbre(arbr1); printf("profondeur : %d\n",profondeur(arbr1)) ; if (Copier(arbr1, &arbr2)) { printf("copie : "); AfficherArbre(arbr1); } /* Etc. */ /* Teste si "fuites" de mémoire */ _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT ); _CrtDumpMemoryLeaks( ); } return 0; 17/01/06 Bac2 - JMD - ArbrBin.ppt 28