PRogram Projet2; (**** GESTION DES CARACTERES SAISIES POUR L'AFFICHAGE EN MODE GRAPHIQUE ***) UNIT inchar : IIUWgraph function(a:integer): integer; var i : integer; begin call move(100,315); call color(grisfonce); case a when 1: call outstring(" : menu principal"); when 2: call outstring(": nouvelle saisie : menu principal"); esac; do i := inkey; if a=1 then if i=27 then exit; fi; else if i=27 or i=13 then exit fi; fi; od; call move(100,315); call outstring(" "); result := i; end inchar; UNIT SAISIE:IIUWGRAPH function(e,x,y:integer):arrayof char; var i,n:integer, c: integer, t :arrayof char; begin array t dim(1:e); for i:=1 to e do t(i):='a'; od; call color(grisclair); do i:=1; c:=inkey; while c<>13 and c<>27 and i<=e do if c-48>=0 and c-48<=9 then t(i):=chr(c); call move(x+i*9,y); call hascii(c); i:=i+1; fi; c:=inkey; od; if t(1)<>'a' then exit; fi; od; result:=t; end SAISIE; UNIT ConvEnt:function(t:arrayof char):integer; var n,i:integer; begin n:=0; for i:=1 to upper(t) do if t(i)<>'a' then n:=n*10+(ord(t(i))-48); fi; od; write(n); result:=n; end ConvEnt; UNIT ConvASC:function(i:integer):arrayof char; var t: arrayof char, n,r:integer; begin array t dim(1:10); n:=1; if i=0 then t(1):=chr(48); n:=n+1; else while I<>0 do t(n):=chr((i mod 10) +48); i:=i div 10; n:=n+1; od; fi; array result dim(1:(n-1)); for r:=1 to (n-1) do result(r):=t(((n-1)-r)+1); od; kill(t); END convasc; UNIT drawmenu: IIUWGRAPH procedure; begin call color(grisclair); call move(0,200); call draw(620,200); call move(620,202); call draw(0,202); call move(240,208); call color(bleu); call outstring("GESTION DES ARBRES 23"); call color(grisclair); call move(0,220); call draw(620,220); call move(5,230); call outstring(" 1-inserer des elements 3-element minimum 5-detruire un arbre"); call move(5,240); call outstring(" 2-supprimer un element 4-element de l'arbre 6-afficher une fouffe"); call move(5,250); call outstring(" 0-quitter le programme"); call move(0,260); call draw(620,260); call move(0,277); call draw(620,277); call move(620,200); call draw(620,330); call draw(0,330); call draw(0,200); END drawmenu; UNIT SelectMenu: IIUWGRAPH function:integer; var choix:integer; begin call color(rouge); call move(1,265); call outstring(" "); call move(5,265); call outstring("Votre choix :"); do choix:=convent(saisie(1,110,265)); if choix>=0 and choix<=6 then exit;fi; od; call move(1,265); call outstring(" "); call move(1,290); call outstring(" "); call move(1,310); call outstring(" "); result:=choix; end; (*** FIN DE LA GESTION DE L'AFFICHAGE... ***) (**** DECLARATION DU TYPE: OBJET... *****) UNIT CObjet: CLASS; UNIT objet:IIUWGRAPH class; unit virtual show: procedure(x,y:integer); end show; unit virtual getvalue:function:integer; end getvalue; unit virtual length:function:integer; end length; end objet; UNIT elem:objet class(val:integer); unit virtual getvalue: function:integer; begin result:=val; end; unit virtual length:function:integer; var t:arrayof char; begin t:=convASC(val); result:=upper(t); end; unit virtual show: procedure(x,y:integer); var a,f,i:integer, c:char, tab:arrayof char; begin tab:=convasc(val); f:=(longueur*8-(upper(tab)*8+(upper(tab)-1)*2))div 2; f:=f+x; for i:=1 to upper(tab) do call move(f,y); c:=tab(i); call hascii(ord(c)); f:=f+10; od; kill(tab); end show; end elem; END Cobjet; (**** fin de la declaration de OBJET ****) UNIT arbre23: CObjet class; VAR racine:arbre,aux:arbre,eq:boolean; (**** STRUCTURE DE L'ARBRE 23 ****) (**** hierarchie: arbre -|-- noeud *******) (** |-- feuille *) UNIT Arbre: IIUWGRAPH class; (** ABSTRACT CLASS **) unit virtual display: procedure(inout h,l:integer); end display; unit virtual getinfo:function(quoi:integer):objet; end getinfo; END arbre; UNIT Noeud: Arbre CLASS (inf,sup:objet); VAR arbG,arbM,arbD:arbre; unit virtual getinfo:function(quoi:integer):objet; begin case quoi when 1:result:=inf; when 2:result:=sup; esac; end getinfo; unit enfants:function:integer; var i:integer; begin i:=0; if arbG<>none then i:=i+1; fi; if arbM<>none then i:=i+1; fi; if arbD<>none then i:=i+1; fi; result:=i; end; UNIT integre:function:boolean; begin result:= (arbD=none); end integre; UNIT virtual display: procedure(inout h,l:integer); var x1,x2:integer; begin x1:=h - (((8*longueur+(longueur-1)*2)*2+4) div 2); x2:=h - (((8*longueur+(longueur-1)*2)*2+4)div 2);; call color(grisclair); call inf.show(x2,l); x2:=x1+(8*longueur+(longueur-1)*2); call color(grisfonce); call move(x2,l-5); call draw(x2,l+10); call move(x2,l); x2:=x2+2; call color(grisclair); call sup.show(x2,l); call color(grisfonce); call move(x2,l); x2:=x2+(8*longueur+(longueur-1)*2); call move(x1-2,l-5); call draw(x2+2,l-5); call draw(x2+2,l+10); call draw(x1-2,l+10); call draw(x1-2,l-5); end display; END noeud; UNIT Feuille: arbre CLASS(e:objet); unit virtual display: procedure(inout h,l:integer); VAR X1,X2:integer; begin x1:=h - ((8*longueur+(longueur-1)*2+4) div 2); call color(rouge); call e.show(x1,l); call color(grisfonce); x2:=x1+(8*longueur+(longueur-1)*2); call move(x1-2,l-5); call draw(x2+2,l-5); call draw(x2+2,l+10); call draw(x1-2,l+10); call draw(x1-2,l-5); end DISPLAY; unit virtual getinfo:function(quoi:integer):objet; begin result:=e; end getinfo; END feuille; UNIT SousArbre: function(a:arbre;element:objet):arbre; var linf,lesup:objet; begin linf:=a.getinfo(inf); lesup:=a.getinfo(sup); if element.getvalue<=linf.getvalue then result:=a qua noeud.arbG; else if lesup.getvalue=-1 then result:=a qua noeud.arbG; else if element.getvalue<=lesup.getvalue then result:=a qua noeud.arbM; else if a qua noeud.arbD=none then result:=a qua noeud.arbM; else result:=a qua noeud.arbD; fi; fi; fi; fi; END sousarbre; UNIT affichage:IIUWGRAPH procedure(r:arbre); var x,y,t,i:integer; begin call drawmenu; x:=5; y:=25; i:=0; call afficheArbre23(r,y,x,i); call move(70,290); call color(rouge); call outstring("les elements de l'arbre sont des nombres inferieurs a 100"); call move(110,310); call outstring(" !!! JUSQU'A 24 ELEMENTS PEUVENT ETRE AFFICHES !!!"); end; Unit affichearbre23: IIUWGRAPH procedure (r:arbre;inout y:integer;x:integer;inout i:integer); const esp=5; var yD,yG,a, t1,t2,t3:integer; begin if r<> none then if r is feuille then call r.display(y,x); else if r qua noeud.arbG is feuille then if r qua noeud.enfants=2 then yD:=y; t1:=y; call affichearbre23(r qua noeud.arbG,y,x+40,i); y:=y+22+esp; t2:=y; t3:=0; call affichearbre23(r qua noeud.arbM,y,x+40,i); y:=y+22+esp; yD:=yD+(51 div 2); i:=yD; call r.display(yD,x); call color(grisfonce); call move(t1,(x+40)-5); call draw(yD,x+10); call move(t2,(x+40)-5); call draw(yD,x+10); else yd:=y; t1:=y; call affichearbre23(r qua noeud.arbG,y,x+40,i); y:=y+22+esp; t2:=y; call affichearbre23(r qua noeud.arbM,y,x+40,i); y:=y+22+esp; t3:=y; call affichearbre23(r qua noeud.arbD,y,x+40,i); y:=y+22+esp; yD:=yD+(60 div 2); i:=yd; call color(grisfonce); call move(t1,(x+40)-5); call draw(yD,x+8); call move(t2,(x+40)-5); call draw(yD,x+8); call move(t3,(x+40)-5); call draw(yD,x+8); call r.display(yd,x); fi; else call affichearbre23(r qua noeud.arbG,y,x+40,i); t1:=i; call affichearbre23(r qua noeud.arbM,y,x+40,i); t2:=i; call affichearbre23(r qua noeud.arbD,y,x+40,i); t3:=i; call color(grisfonce); if r qua noeud.enfants=2 then yd:=t1+((t2-t1)/2); call move(t1,x+35); call draw(yd,x+8); call move(t2,x+35); call draw(yd,x+8); else yd:=t1+((t3-t1)/2); call move(t1,x+35); call draw(yd,x+8); call move(t2,x+35); call draw(yd,x+8); call move(t3,x+35); call draw(yd,x+8); fi; call r.display(yd,x); i:=yd; fi; fi; fi; end affichearbre23; unit suppression:function(d:arbre,num:objet):boolean; var delete:boolean,cousin:arbre; begin (**** INITIALISATION ****) if d<>none then delete:=false; cousin:=none; if member(d,num) then call supprime(d,num,delete,cousin); result:=true; else result:=false; fi; else result:=false; fi; end; UNIT supprime: procedure(p:arbre,n:objet;inout deleted:boolean,aux:arbre); var linf,lesup:objet, fils:arbre; begin linf:=p.getinfo(1); lesup:=p.getinfo(2); if p is feuille then (** le pere est une feuille **) kill(p); racine:=none; deleted:=true; else fils:=sousarbre(p,n); if fils is feuille then (* fils est une feuille **) deleted:=true; (* on le supprime*) if p qua noeud.enfants=2 then (* l'arbre n'est plus un arbre 23 *) if n.getvalue=linf.getvalue then aux:=p qua noeud.arbM; else aux:=p qua noeud.arbG; fi; kill(fils); if p=racine then racine:=aux; fi; kill(p); (* on supprime le noeud car il a qu'un fils...*) else kill(fils); call decale(p); aux:=none; fi; ELSE (* fils est un noeud..*) call supprime(fils,n,deleted,aux); if deleted then if aux<>none then if p qua noeud.enfants=1 then if p qua noeud.arbg=none then p qua noeud.arbG:=p qua noeud.arbM; p qua noeud.arbM:=none; p qua noeud.inf:=supI(p qua noeud.arbG); p qua noeud.sup:=new elem(-1); else p qua noeud.sup:=new elem(-1); fi; else call decale(p); fi; fils:=sousarbre(p,aux.getinfo(inf)); if fils qua noeud.enfants=3 then aux:=ordre(aux.getinfo(inf),fils,aux); call ordonne(aux.getinfo(inf),p,aux); aux:=none; else call ordonne(aux.getinfo(inf),fils,aux); p qua noeud.inf:=supI(p qua noeud.arbG); p qua noeud.sup:=supI(p qua noeud.arbM); aux:=none; fi; if p qua noeud.enfants=1 then if p=racine then racine:=fils; else aux:=fils; fi; kill(p); fi; else p qua noeud.inf:=supI(p qua noeud.arbG); p qua noeud.sup:=supI(p qua noeud.arbM); fi; fi; FI; fi; END SUPPRIME; Unit root:function:arbre; begin result:=racine; end; UNIT reset:procedure(r:arbre); begin if r<>none then if r is feuille then kill(r qua feuille.e); kill(r); else call reset(r qua noeud.arbG); call reset(r qua noeud.arbM); call reset(r qua noeud.arbD); kill(r qua noeud.inf); kill(r qua noeud.sup); kill(r); fi; fi; end reset; UNIT minimum:function(r:arbre):elem; begin if r<>none then if r is feuille then result:=r.getinfo(1); else result:=minimum(r qua noeud.arbG); fi; else result:=none; fi; end minimum; UNIT member: function(per:arbre,value:objet):boolean; var fil:arbre, cettevaleur:objet; Begin if per<>none then if per is noeud then fil:=SousArbre(per,value); else (* l'arbre est constitu‚ d'une seule feuille *) fil:=per; per:=none; fi; fi; if fil<>none then if fil is noeud then result:=member(fil,value); else cettevaleur:=fil.getinfo(leave); result:=(cettevaleur.getvalue=value.getvalue); fi; else result:=false; fi; END member; (**** procedures utilis‚es dans les procedures INSERTION,SUPPRESSION,MEMBER... *******) Unit ordonne:procedure(valeur:objet,nd,obj:arbre); (* ordonne le noeud "ND" apr‚s insertion du nouvel objet *) (* le noeud comporte alors 3 fils...*) var Lesup,Linf:objet; begin Linf:=nd.getinfo(inf); lesup:=nd.getinfo(sup); if valeur.getvaluenone then if r is feuille then theleave:=r.getinfo(leave); result:=theleave; else if r qua noeud.arbD=none then result:=supI(r qua noeud.arbM); else result:=supI(r qua noeud.arbD); fi; fi; else result:=none; fi; end supI; (************************************************************************************) Unit inserer: IIUWGRAPH procedure; var num:file, a:integer; var exist:boolean, d:arbre, rt:elem, components,i:integer; begin i:=100; do call move(5,290); call color(grisfonce); call outstring("Element a inserer :"); rt:= new elem (ConvEnt(SAISIE(longueur,160,290))); d:=racine; exist:=member(d,rt); if not exist then call insertion(d,rt); else call color(rouge); call move(200,290); call outstring(" ... element existe deja! ..."); fi; a:=inchar(2); if a=27 then exit; else if not exist then call move(50,300); call color(bleu); call outstring("===>"); call rt.show(i,300); i:=i+22; fi; fi; call move(1,290); call outstring(" "); od; call move(1,290); call outstring(" "); call move(1,300); call outstring(" "); end inserer; UNIT insertion:procedure(pere:arbre,v:objet); var p,fils:arbre, linf,lesupdupere,lesupduaux:objet; Begin if pere<>none then if pere is noeud then fils:=SousArbre(pere,v); else (* l'arbre est constitu‚ d'une seule feuille *) fils:=pere; fi; linf:=fils.getinfo(inf); if fils is feuille then if pere=fils then racine:=new noeud(v,v); if linf.getvaluenone then if pere=racine then if pere qua noeud.integre then call ordonne(aux qua noeud.sup,pere,aux); else p:=ordre(aux qua noeud.sup,pere,aux); lesupduPERE:=pere.getinfo(sup); lesupduAUX:=p.getinfo(sup); if LesupduAUX.getvalue>LesupduPERE.getvalue then racine:=new noeud(pere qua noeud.sup,p qua noeud.sup); racine qua noeud.arbG:=pere; racine qua noeud.arbM:=p; else racine:=new noeud(p qua noeud.sup,pere qua noeud.sup); racine qua noeud.arbM:=pere; racine qua noeud.arbG:=p; fi; fi; eq:=false; aux:=none; else if pere qua noeud.integre then call ordonne(aux qua noeud.sup,pere,aux); aux:=none; else aux:=ordre(aux qua noeud.sup,pere,aux); fi; fi; else (* mise a jour des noeud uniquement*) pere qua noeud.inf:= supI(pere qua noeud.arbG); pere qua noeud.sup:= supI(pere qua noeud.arbM); fi; fi; fi; else racine:=new feuille(v); fi; END insertion; BEGIN racine:=none; aux:=none; eq:=false; END arbre23; (************************* PROGRAMME PRINCIPAL ******************************) CONST longueur=2, rouge=4, vert=2, marron=6, grisclair=7, grisfonce=8, violet=5, vertclair=10, bleu=9, sup=2, couleur=3, inf=1,leave=1; VAR i:integer; BEGIN pref iiuwgraph block begin pref arbre23 block var rt:elem; begin call gron(2); do call cls; racine:=root; call affichage(racine); call drawmenu; i:=selectmenu; call move(1,265); call color(rouge); case i when 1: call outstring(" Insertion d'un ou plusieurs elements dans l'arbre"); call inserer; when 2: call outstring(" Suppression d'un element dans l'arbre"); call move(10,280); call color(rouge); call outstring("element a supprimer:"); rt:=new elem(convent(saisie(2,200,280))); call color(grisclair); call move(130,300); if suppression(racine,rt) then call outstring("L'ELEMENT A ETE SUPPRIME !"); else call outstring("L'ELEMENT A SUPPRIMER N'APPARTIENT PAS A L'ARBRE !"); fi; i:=inchar(1); kill(rt); when 3: call outstring(" Recherche de l'element minimum appartenant a l'arbre"); call move(10,300); call color(grisclair); call outstring("l'element minimum est -->"); rt:=minimum(racine); call color(rouge); if rt<>none then call rt.show(250,300); i:=inchar(1); fi; when 4: call outstring(" Interrogation sur l'appartenance d'un element..."); call move(10,280); call color(grisfonce); call outstring("element :"); rt:=new elem(convent(saisie(2,200,280))); call move(100,300); call color(grisclair); if member(racine,rt) then call outstring("L'ELEMENT APPARTIENT A L'ARBRE !"); else call outstring("L'ELEMENT N'APPARTIENT PAS A L'ARBRE !"); fi; kill(rt); i:=inchar(1); when 5: call reset(racine); when 0: exit; esac; od; call reset(racine); kill(rt); call groff; end; (* block arbre23 *) end; (* block IIUWGRAPH *) END projet2;