program bicolore; (* ANNEE UNIVERSITAIRE 1993/1994 : Universit‚ de Pau *) (* DATE DE REMISE : 15 JANVIER 1994 *) (* *) (* SUJET : ARBRES BICOLORES *) (* *) (* GROUPE 2 , LICENCE INFORMATIQUE , LI1 *) (* *) (* *) (* MARIE HEGUY *) (* JACQUES LATAPIE *) (* SUJET PROPOSE PAR MME MIRKOWSKA *) unit noeud:class; var elem:integer,gauche,droite,pere:noeud,couleur:integer; end noeud; (* RECHERCHE DU MINIMUN *) unit recmin:function(t:noeud):noeud; begin if t.gauche=z then result:=t; else result:=recmin(t.gauche); fi; end recmin; (* RECHERCHE DU MAXIMUM *) unit recmax:function(t:noeud):noeud; begin if t.droite=z then result:=t; else result:=recmax(t.droite); fi; end recmax; (* SUPPRESSION D'UN ELEMENT COMME DANS UN ARBRE BST *) unit suppression:iiuwgraph procedure(inout t:noeud,supp:noeud,remplacant:noeud); var locale:noeud; begin if supp.gauche=z or supp.droite=z then remplacant:=supp; else remplacant:=recmin(supp.droite); fi; if remplacant.gauche<>z then locale:=remplacant.gauche; else locale:=remplacant.droite; fi; locale.pere:=remplacant.pere; if remplacant.pere=remplacant then t:=locale; t.pere:=t; else if remplacant=remplacant.pere.gauche then remplacant.pere.gauche:=locale; else remplacant.pere.droite:=locale; fi; fi; if remplacant<>supp then supp.elem:=remplacant.elem;fi; if remplacant.couleur=0 then call suppresmaj(t,locale);fi; end suppression; (* ROTATION ET INVERSION DES COULEURS APRES SUPPRESSION *) unit suppresmaj:iiuwgraph procedure(inout t:noeud,rond:noeud); var local:noeud,rep:integer; begin while rond<>t and rond.couleur=0 do if rond=rond.pere.gauche then local:=rond.pere.droite; if local.couleur=1 then local.couleur:=0; rond.pere.couleur:=1; call gauch(t,rond.pere); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Visua. aprŠs rot. Gauche sur "); call writeinteger(rond.pere.elem); call outstring(" "); rep:=inchar; call cls; local:=rond.pere.droite; fi; if local.gauche.couleur=0 and local.droite.couleur=0 then local.couleur:=1; rond:=rond.pere; else if local.droite.couleur=0 then local.gauche.couleur:=0; local.couleur:=1; call droit(t,local); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Rotation Droite sur "); call writeinteger(local.elem); call outstring(" "); rep:=inchar; call cls; local:=rond.pere.droite; fi; local.couleur:=rond.pere.couleur; rond.pere.couleur:=0; local.droite.couleur:=0; call gauch(t,rond.pere); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Rotation Gauche sur "); call writeinteger(rond.pere.elem); call outstring(" "); rep:=inchar; call cls; rond:=t; fi; else local:=rond.pere.gauche; if local.couleur=1 then local.couleur:=0; rond.pere.couleur:=1; call droit(t,rond.pere); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Rotation Droite sur "); call writeinteger(rond.pere.elem); call outstring(" "); rep:=inchar; call cls; local:=rond.pere.gauche; fi; if local.droite.couleur=0 and local.gauche.couleur=0 then local.couleur:=1; rond:=rond.pere; else if local.gauche.couleur=0 then local.droite.couleur:=0; local.couleur:=1; call gauch(t,local); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Rotation Gauche sur "); call writeinteger(local.elem); call outstring(" "); rep:=inchar; call cls; local:=rond.pere.gauche; fi; local.couleur:=rond.pere.couleur; rond.pere.couleur:=0; local.gauche.couleur:=0; call droit(t,rond.pere); call cls; call visua(t,0.5,1,0,0); call color(14); call move(2,340); call outstring("Rotation Droite sur "); call writeinteger(rond.pere.elem); call outstring(" "); rep:=inchar; call cls; rond:=t; fi; fi; od; rond.couleur:=0; end suppresmaj; (* INSERSION COMME DANS UN ARBRE BST *) unit insert_bst: procedure(nb:integer;inout r:noeud,x:noeud,p:noeud,trouve:integer); begin if r.elem=nb then if r=z then r:=new noeud; r.elem:=nb; if p=z then r.pere:=r; else r.pere:=p; fi; r.droite:=z; r.gauche:=z; x:=r; else (*("CET ELEMENT EST DEJA INSERE !!! ");*) trouve:=1; fi; else if nbracine) and (x.pere.couleur=1)) do call cls; call visua(racine,0.5,1,0,0); call color(14); call move(2,340); call outstring("On a deux noeuds rouges cons‚cutifs "); call writeinteger(x.elem); call outstring(" et "); call writeinteger(x.pere.elem); call outstring(" "); rep:=inchar; call cls; if x.pere=x.pere.pere.gauche then y:=x.pere.pere.droite; if y.couleur=1 then (* L'oncle de x.elem est rouge donc inversion des couleurs*) x.pere.couleur:=0; y.couleur:=0; x.pere.pere.couleur:=1; call visua(racine,0.5,1,0,0); call color(14); call move(2,340); call outstring("Visualisation aprŠs inversion des couleur "); rep:=inchar; call cls; x:=x.pere.pere; else if x=x.pere.droite then x:=x.pere; call gauch(racine,x); call cls; call visua(racine,0.5,1,0,0); call color(14); call move(2,340); call outstring("Visualisation aprŠs rot. gauche au niveau de "); call writeinteger(x.elem); call outstring(" "); rep:=inchar; call cls; fi; x.pere.couleur:=0; x.pere.pere.couleur:=1; if x.pere.pere=racine then valeur:=x.pere; else valeur:=x.pere.pere.pere; fi; call droit(racine,x.pere.pere); x.pere.pere:=valeur; call cls; call visua(racine,0.5,1,0,0); call color(14); call move(2,340); call outstring("Visu.apŠs r‚tab. des couleurs et rot. D sur "); call writeinteger(x.pere.pere.elem); call outstring(" "); rep:=inchar; call cls; fi; else y:=x.pere.pere.gauche; if y.couleur=1 then (* L'oncle de x.elem est rouge donc inversion des couleurs*) x.pere.couleur:=0; y.couleur:=0; x.pere.pere.couleur:=1; call cls; call visua(racine,0.5,1,0,0); call color(14); call move(2,340); call outstring("Visua. aprŠs inversion des couleurs "); rep:=inchar; call cls; x:=x.pere.pere; else if x=x.pere.gauche then x:=x.pere; call droit(racine,x); call cls; call visua(racine,0.5,1,0,0); call move(2,340); call color(14); call outstring("Visualisation aprŠs rotation droite au niveau de "); call writeinteger(x.elem); call outstring(" "); rep:=inchar; call cls; fi; x.pere.couleur:=0; x.pere.pere.couleur:=1; if x.pere.pere=racine then valeur:=x.pere; else valeur:=x.pere.pere.pere; fi; call gauch(racine,x.pere.pere); x.pere.pere:=valeur; call cls; call visua(racine,0.5,1,0,0); call move(2,340); call color(14); call outstring("Visu.aprŠs r‚tab. des couleurs et rot. gauche sur "); call writeinteger(x.pere.pere.elem); call outstring(" "); rep:=inchar; call cls; fi; fi; od; racine.couleur:=0; end insert; (* ROTATION GAUCHE *) unit gauch:procedure(inout t:noeud;inout aux1:noeud); var fils:noeud; begin fils:=aux1.droite; aux1.droite:=fils.gauche; if aux1<>t then fils.pere:=aux1.pere; else fils.pere:=fils; fi; if fils.gauche<>z then fils.gauche.pere:=aux1;fi; if aux1.pere=aux1 then t:=fils; else if aux1=aux1.pere.gauche then aux1.pere.gauche:=fils; else aux1.pere.droite:=fils; fi; fi; fils.gauche:=aux1; aux1.pere:=fils; end gauch; (* ROTATION DROITE *) unit droit:procedure(inout t:noeud;inout aux2:noeud); var child:noeud; begin child:=aux2.gauche; aux2.gauche:=child.droite; if child.droite<>z then child.droite.pere:=aux2;fi; if aux2<>t then child.pere:=aux2.pere; else child.pere:=child; fi; if aux2.pere=aux2 then t:=child; else if aux2=aux2.pere.droite then aux2.pere.droite:=child; else aux2.pere.gauche:=child; fi; fi; child.droite:=aux2; aux2.pere:=child; end droit; (* RECHERCHE D'UN ELEMENT QUELCONQUE *) unit recherche: iiuwgraph procedure(r:noeud;nb:integer;inout pointeur:noeud); var rep:integer; begin while r<>z do call cls; call move(200,100); if r.elem=nb then call outstring("Element "); call writeinteger(nb); call outstring(" est trouv‚ dans l'arbre"); call move(200,120); call outstring(" COULEUR = "); if r.couleur=1 then call outstring(" ROUGE "); else call outstring(" NOIR "); fi; call move(200,140); call outstring(" PERE = "); call writeinteger(r.pere.elem); call move(200,160); if r.gauche<>z then call outstring("FILS GAUCHE = "); call writeinteger(r.gauche.elem);fi; call move(200,180); if r.droite<>z then call outstring("FILS DROIT = "); call writeinteger(r.droite.elem);fi; call move(0,340); call outstring("APPUYEZ SUR POUR CONTINUER .. "); rep:=inchar; pointeur:=r; return; else if nb>r.elem then r:=r.droite; else r:=r.gauche; fi; fi; od; if r=z then call move(200,160); call writeinteger(nb); call outstring(" N'APPARTIENT PAS A L'ARBRE "); call move(0,340); call outstring("APPUYEZ SUR POUR CONTINUER ..."); rep:=inchar; pointeur:=z; fi; end recherche; (* PROCEDURES ET FONCTIONS UTILISANT LE MODE GRAPHIQUE *) unit inchar: iiuwgraph function:integer; var i:integer; begin do i:=inkey; if i=/=0 then exit fi; od; result:=i; end inchar; unit ReadInteger : iiuwgraph function : integer; var X,Y,i, OrdN, j : integer, Number : arrayof integer; (* i - liczba wprowadzonych znakow *) begin array Number dim( 1 : 4 ); i:= 0 ; X := InXPos; Y := InYPos; do OrdN:=inchar; if i = 4 or (OrdN < 48 and OrdN > 57) then exit fi; case OrdN when 48 :i:=i+1; Number(i):=0; when 49 :i:=i+1; Number(i):=1; when 50 :i:=i+1; Number(i):=2; when 51 :i:=i+1; Number(i):=3; when 52 :i:=i+1; Number(i):=4; when 53 :i:=i+1; Number(i):=5; when 54 :i:=i+1; Number(i):=6; when 55 :i:=i+1; Number(i):=7; when 56 :i:=i+1; Number(i):=8; when 57 :i:=i+1; Number(i):=9; when 8 :if i>0 then Number( i ) := 0; i := i - 1; fi; when 13 :if i > 0 then exit fi ; esac; if Number( 1 ) <> 0 then call Move( X,Y ); call hascii( 0 ); call hascii(48+Number( 1 )); call hascii( 0 ); fi; if i = 2 then call Move( X + 8, Y ); call hascii( 0 ); call hascii( 48 + Number( 2 )); call hascii( 0 ); fi; od; if Number( 1 ) = 0 and Number( 2 ) = 0 then call Move( X,Y ); call hascii( 0 ); call hascii( 48 ); call hascii( 0 ); fi; if i = 1 then result := Number( 1 ); else result := 10 * Number( 1 ) + Number ( 2 ); fi; kill( Number ); end ReadInteger; unit WriteInteger:iiuwgraph procedure(Number:integer); var i,j:integer; begin if Number < 10 then call HASCII( 0 ); call HASCII( Number + 48 ); call HASCII( 0 ); else i:=Number div 10; j:=(Number - (i * 10)); call HASCII(0); call HASCII( i + 48 ); call HASCII(0); call HASCII( j + 48 ); fi; end WriteInteger; (* FIN DES UNITES DE LECTURE ET ECRITURE EN MODE GRAPHIQUE *) (* SAISIE D'UN ELEMENT *) unit saisie : iiuwgraph procedure(output nombre:integer); begin call cls; call move(200,100); call outstring("ENTREZ UN ENTIER : "); nombre:=readinteger; end; (* AFFICHAGE DU MENU PRINCIPAL *) unit menu:iiuwgraph procedure(output chx:integer); begin call cls; call color(14); call move(180,50); call outstring("IMPLEMENTATION DES ARBRES BICOLORES"); call move(280,100); call outstring("MENU PRINCIPAL"); call move(200,140); call outstring("INSERTION : 1"); call move(200,160); call outstring("SUPPRESSION : 2"); call move(200,180); call outstring("VISUALITION DE L'ARBRE : 3"); call move(200,200); call outstring("RECHERCHE D'UN ELEMENT : 4"); call move(200,220); call outstring("RECHERCHE DU MININUM : 5"); call move(200,240); call outstring("RECHERCHE DU MAXIMUM : 6"); call move(200,260); call outstring("FIN DU TRAITEMENT : 9"); call move(200,300); call outstring(" VOTRE CHOIX : "); chx:=readinteger; end; (* AFFICHAGE DE L'ARBRE *) unit visua: procedure(t:noeud;input coeff:real,sup:real,inf:real,niveau:integer); var posx:real,posy,i,j:integer; begin pref iiuwgraph block begin if t=/= z then niveau:=niveau+1; posx:=(coeff*(sup-inf))+inf; posy:=(niveau*35); if niveau=/=1 then (*call move(inxpos+8,inypos+8);*) call draw(posx*640,posy); (*call move(inxpos-8,inypos-8);*) fi; call move(round(posx*640),posy); call HASCII(0); (*call writeinteger(t.elem);*) (*call HASCII(t.elem+48);*) call move(inxpos+4,inypos); if t.couleur=1 then call color(12); else call color(7); fi; if t.elem<10 then call HASCII(0); call HASCII(t.elem+48); call HASCII(0); else i:=t.elem div 10; j:=t.elem-i*10; call HASCII(0); call HASCII(i+48); call HASCII(0); call HASCII(j+48); fi; call color(1); call move(inxpos-20,inypos); call visua(t.gauche,0.5,posx,inf,niveau); call move(round(posx*640)+8,posy+8); call visua(t.droite,0.5,sup,posx,niveau); call move(round(posx*640)+8,posy+8); fi; end; end visua; (* PROGRAMME PRINCIPAL *) var choix,a,trouve,i,ligne:integer, x,z,racine,min,max,pnteur,remp:noeud, rp:char; BEGIN pref iiuwgraph block (* UTILISATION DU MODE GRAPHIQUE SUR ECRAN EGA/VGA *) begin z:=new noeud; choix:=0; z.couleur:=0; racine:=z; call gron(5); while (choix<>9) do call menu(choix); case choix when 1 : call cls; call move(200,100); call saisie(a); z.elem:=a; trouve:=0; call insert_bst(a,racine,x,racine,trouve); if trouve=0 then call insert(x,racine); fi when 2 : call cls; call move(200,100); call saisie(a); call recherche(racine,a,pnteur); if pnteur<>z then call suppression(racine,pnteur,remp); fi; when 3 : if racine<>z then call cls; call visua(racine,0.5,1,0,0); else call cls; call move(200,100); call outstring(" ARBRE VIDE "); fi; call color(14); call move(0,340); call outstring("APPUYEZ SUR POUR CONTINUER ... "); rp:=chr(inchar) when 4 : call cls; call move(200,100); call saisie(a); call recherche(racine,a,pnteur) when 5 : call cls; if racine<>z then if racine.gauche<>z then min:=recmin(racine.gauche); else min:=racine; fi; call move(200,100); call outstring("LE MININUM DE L'ARBRE EST: "); call WriteInteger(min.elem); else call move(200,100); call outstring("OPERATION IMPOSSIBLE : ARBRE VIDE "); call move(0,340); call outstring("APPUYEZ SUR POUR CONTINUER ..."); fi; rp:=chr(inchar) when 6 : call cls; if racine<>z then if racine.droite<>z then max:=recmax(racine.droite); else max:=racine; fi; call move(200,100); call outstring("LE MAXIMUM DE L'ARBRE EST: "); call WriteInteger(max.elem); else call move(200,100); call outstring("OPERATION IMPOSSIBLE : ARBRE VIDE "); fi; call move(0,340); call outstring("APPUYEZ SUR POUR CONTINUER ... "); rp:=chr(inchar); esac; od; call groff; call endrun; end; END bicolore;